Làm cách nào để tạo Máy nhắn tin Chế độ xem Android với chỉ báo dấu chấm?


Câu trả lời:


318

Tất cả những gì chúng ta cần là: ViewPager , TabLayout và 2 drawable cho các dấu chấm được chọn và mặc định.

Đầu tiên, chúng ta phải thêm TabLayoutvào bố cục màn hình của mình và kết nối nó với ViewPager. Chúng ta có thể làm điều này theo hai cách:


Lồng TabLayouttrongViewPager

<androidx.viewpager.widget.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.tabs.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</androidx.viewpager.widget.ViewPager>

Trong trường hợp TabLayoutnày sẽ được tự động kết nối với ViewPager, nhưng TabLayoutsẽ ở bên cạnh ViewPager, không qua nó.


Tách rời TabLayout

<androidx.viewpager.widget.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

Trong trường hợp này, chúng tôi có thể đặt TabLayoutbất cứ nơi nào, nhưng chúng tôi phải kết nối TabLayoutvới ViewPagerlập trình

ViewPager pager = (ViewPager) view.findViewById(R.id.photos_viewpager);
PagerAdapter adapter = new PhotosAdapter(getChildFragmentManager(), photosUrl);
pager.setAdapter(adapter);

TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(pager, true);

Khi chúng tôi tạo bố cục của chúng tôi, chúng tôi phải chuẩn bị các dấu chấm của chúng tôi. Vì vậy, chúng ta tạo ra ba tác phẩm: selected_dot.xml, default_dot.xmltab_selector.xml.


chọn_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@color/colorAccent"/>
        </shape>    
    </item>
</layer-list>

default_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@android:color/darker_gray"/>
        </shape>    
    </item>
</layer-list>

tab_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/selected_dot"
          android:state_selected="true"/>

    <item android:drawable="@drawable/default_dot"/>
</selector>

Bây giờ chúng tôi chỉ cần thêm 3 dòng mã vào TabLayouttrong bố cục XML của chúng tôi.

app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"

Để ViewPager2đọc bài viết này:

ViewPager (2) với chỉ báo dấu chấm tại Medium.com

Up-phiếu được chào đón ;-)


18
bạn tốt hơn nên đặt nó trong phần tài liệu. nó đã giúp
Erfan GLMPR


3
@AmitSingh Bạn có thể sử dụng app:tabMaxWidthtrong TabLayout
RediOne1

3
Tôi không biết nếu tôi không làm theo đúng hướng dẫn nhưng tôi cũng phải thêm các mục sau để chỉ hiển thị các dấu chấm có khoảng trắng ở giữa chúng: app:tabMaxWidth="30dp" app:tabTextColor="@color/transparent2" app:tabSelectedTextColor="@color/transparent2" app:tabIndicatorHeight="0dp" android:layout_gravity="bottom|center"
Bảy

3
Để xóa khoảng cách giữa các ứng dụng dấu chấm: tabPaddingStart = "@ dimen / margin_7.5" ứng dụng: tabPaddingEnd = "@ dimen / margin_7.5"
dev_mg99

30

Trước tiên, hãy tạo bố cục, trong đó cung cấp một linerLayout cho Dots hiển thị trên Chế độ xem của bạn

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>


    <LinearLayout
        android:id="@+id/pager_dots"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="10dp"
        android:background="@android:color/transparent"
        android:gravity="center_horizontal"
        android:orientation="horizontal">
    </LinearLayout>

</RelativeLayout>

Sau đó tạo 2 drawables

1. Không thể chọn Drawable

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="oval" xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@android:color/transparent"/>
    <size android:width="12dp" android:height="12dp"/>

    <stroke android:width="1dp" android:color="#ffffff"/>
</shape>

2. Có thể vẽ

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="oval" xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@android:color/transparent"/>
    <size android:width="12dp" android:height="12dp"/>

    <stroke android:width="1dp" android:color="#000000"/>
</shape>

Sau đó thiết lập bộ chuyển đổi

private LinearLayout llPagerDots;
private ViewPager viewPager;
private ArrayList<String> eventImagesUrl;
private HomeViewPagerAdapter homeViewPagerAdapter;
private ImageView[] ivArrayDotsPager;

public void setUpViewPager() {
    viewPager = (ViewPager) findViewById(R.id.view_pager);
    llPagerDots = (LinearLayout) findViewById(R.id.pager_dots);

    homeViewPagerAdapter = new HomeViewPagerAdapter(mContext, eventImagesUrl);

    viewPager.setAdapter(homeViewPagerAdapter);

    setupPagerIndidcatorDots();

    ivArrayDotsPager[0].setImageResource(R.drawable.page_indicator_selected);

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            for (int i = 0; i < ivArrayDotsPager.length; i++) {
                ivArrayDotsPager[i].setImageResource(R.drawable.page_indicator_unselected);
            }
            ivArrayDotsPager[position].setImageResource(R.drawable.page_indicator_selected);
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
}

Tạo một phương thức setupPagerIndidcatorDots ():

private void setupPagerIndidcatorDots() {
    ivArrayDotsPager = new ImageView[eventImagesUrl.size()];
    for (int i = 0; i < ivArrayDotsPager.length; i++) {
        ivArrayDotsPager[i] = new ImageView(getActivity());
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.setMargins(5, 0, 5, 0);
        ivArrayDotsPager[i].setLayoutParams(params);
        ivArrayDotsPager[i].setImageResource(R.drawable.page_indicator_unselected);
        //ivArrayDotsPager[i].setAlpha(0.4f);
        ivArrayDotsPager[i].setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                view.setAlpha(1);
            }
        });
        llPagerDots.addView(ivArrayDotsPager[i]);
        llPagerDots.bringToFront();
    }

Và là HomeViewPagerAdaptergì?
CoolMind 17/07/18

Sửa đổi onPage Chọn một chút để hoạt động hoàn hảo như bên dưới ghi đè lên niềm vui onPageSelected (vị trí: Int) {for (i in 0 cho đến ivArrayDotsPager !!. Size) {if (i! = Position) ivArrayDotsPager !! [i] .setImageDrawable (Context applicationContext, R.drawable.unselected_dot)) khác ivArrayDotsPager !! [i] .setImageDrawable (ContextCompat.getDrawable (applicationContext, R.drawable.selected_dot))} LinearLayout !! bringToFront ()}.
trung kiên

19

Bạn có thể kiểm tra thư viện của tôi để xử lý yêu cầu của bạn: https://github.com/tommybuonomo/dotsindicator

Trong bố cục XML của bạn

  <com.tbuonomo.viewpagerdotsindicator.DotsIndicator
      android:id="@+id/dots_indicator"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerHorizontal="true"
      app:dotsColor="@color/colorPrimary"
      app:dotsSize="16dp"
      app:dotsWidthFactor="3"
      />

Trong mã Java của bạn

dotsIndicator = (DotsIndicator) findViewById(R.id.dots_indicator);
viewPager = (ViewPager) findViewById(R.id.view_pager);
adapter = new ViewPagerAdapter();
viewPager.setAdapter(adapter);
dotsIndicator.setViewPager(viewPager);

Rất đơn giản để sử dụng và trông tuyệt vời đặc biệt là với các hình ảnh động ... cảm ơn! Tuy nhiên, tôi đã phải thêm tools:replace="android:label"vào applicationthẻ AndroidManifest.xmlđể thoát khỏi lỗi về thẻ đó được xác định hai lần và gây ra lỗi xây dựng lớp.
Fat Monk

Tôi đang gặp một gradlelỗi, mặc dù Error:(39, 20) All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 27.0.0, 25.3.1. Examples include 'com.android.support:support-compat:27.0.0' and 'com.android.support:animated-vector-drawable:25.3.1'- làm thế nào tôi có thể sửa lỗi này?
Fat Monk

Cách cuộn tự động DotsTheicator
Shivam Kumar

này

3
<android.support.v4.view.ViewPager
      android:id="@+id/vpImage"
      android:layout_width="match_parent"
      android:layout_height="@dimen/_120sdp" />


<android.support.design.widget.TabLayout
      android:id="@+id/tlImage"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:tabBackground="@drawable/selector_product_image"
      app:tabGravity="center"
      app:tabIndicatorHeight="0dp"
      app:tabMaxWidth="12dp"
      app:tabRippleColor="@null" />

ImageAdapter imageAdapter = new ImageAdapter(context, arrayList);
vpImage.setOffscreenPageLimit(1);
vpImage.setAdapter(imageAdapter);
tlImage.setupWithViewPager(vpImage);

selector_product_image.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/image_selected" android:state_selected="true" />
    <item android:drawable="@drawable/image_unselected" />

</selector>

image_selected.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="4dp"
            android:useLevel="false">
            <solid android:color="@color/colorAccent" />
        </shape>
    </item>
</layer-list>

image_unelected.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="4dp"
            android:useLevel="false">
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</layer-list>

ImageAd CHƯƠNG.java

class ImageAdapter extends PagerAdapter {

  private Context context;
  private ArrayList<ImageModel> arrayList;
  private LayoutInflater layoutInflater;

  public ImageAdapter(Context context, ArrayList<ImageModel> arrayList) {
      this.context = context;
      this.arrayList = arrayList;
      this.layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }

  @Override
  public int getCount() {
      return arrayList.size();
  }

  @Override
  public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
      return view == ((View) o);
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
      View view = layoutInflater.inflate(R.layout.row_slider_image, container, false);

      AppCompatImageView ivProductImage = view.findViewById(R.id.ivProductImage);

      if (!TextUtils.isEmpty(arrayList.get(position).getImage())) {
          Glide.with(context)
                  .load(arrayList.get(position).getImage())
                  .apply(new RequestOptions().placeholder(R.drawable.no_image).error(R.drawable.no_image))
                  .into(ivProductImage);
      }

      container.addView(view);
      return view;
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
      container.removeView((View) object);
  }
}

row_slider_image.xml

<android.support.v7.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.AppCompatImageView
        android:id="@+id/ivProductImage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/no_image" />

</android.support.v7.widget.LinearLayoutCompat>

1

Xml của bạn

  <RelativeLayout
                android:id="@+id/rl_speed"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_above="@+id/ll_dashboard_buttons"
                android:layout_below="@+id/ib_menu">

                <com.smart.gps.speedometer.app.utils.SmartViewPager
                    android:id="@+id/view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" 
                   app:layout_behavior="@string/appbar_scrolling_view_behavior">
                   </com.smart.gps.speedometer.app.utils.SmartViewPager>

                   <android.support.design.widget.TabLayout
                    android:id="@+id/sliding_tabs"
                    android:layout_alignParentBottom="true"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:tabBackground="@drawable/tab_selector"
                    app:tabIndicatorHeight="0dp"
                    app:tabGravity="center"
                    />

tạo ra một drawable. nhấp chuột phải vào drawable -> new -> Drawable tên tài nguyên tệp đó

tab_selector.xml

<item android:drawable="@drawable/selected_tab"
    android:state_selected="true"/>

<item android:drawable="@drawable/unselected_tab"/>

Bây giờ có thêm hai tệp xml. tạo thêm hai tệp xml với tên được tôn trọng. đây là chỉ báo chọn và chỉ báo không được chọn

chọn_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="4dp"
            android:useLevel="false">
            <solid android:color="@color/highspeed"/>
        </shape>
    </item>
</layer-list>

bỏ chọn_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="2dp"
            android:useLevel="false">
            <solid android:color="@android:color/darker_gray"/>
        </shape>
    </item>
</layer-list>

Có lẽ SmartViewPagerlà xem tùy chỉnh của bạn.
CoolMind

1

Khi bạn muốn một cái gì đó tương tự như thế này với ViewPager2Kotlin mới nhất

Mọi thứ đều tự giải thích, không cần phải giải thích!

nhập mô tả hình ảnh ở đây

1. Hoạt động hoặc đoạn của bạn

val imageList = listOf(
        ImageModel(R.drawable.offer1),
        ImageModel(R.drawable.splash),
        ImageModel(R.drawable.offer1),
        ImageModel(R.drawable.splash2)
    )

    val adapter = HomeOffersAdapter()
    adapter.setItem(imageList)
    photos_viewpager.adapter = adapter

    TabLayoutMediator(tab_layout, photos_viewpager) { tab, position ->
    }.attach()
}

2. Bố cục

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_200">

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dp_200" />

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_gravity="bottom|center"
    app:tabBackground="@drawable/tab_selector"
    app:tabGravity="center"
    app:tabIndicatorHeight="0dp"
    app:tabSelectedTextColor="@android:color/transparent"
    app:tabTextColor="@android:color/transparent" />

3. Có thể vẽ: tab_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/dot_selected" android:state_selected="true" />
<item android:drawable="@drawable/dot_default" />

4. Có thể vẽ: dot_selected.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="@dimen/dp_8"
android:useLevel="false">

<solid android:color="@color/colorPrimary" />

<stroke
    android:width="@dimen/dp_1"
    android:color="@android:color/white" />

5. Có thể vẽ: dot_default.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="@dimen/dp_8"
android:useLevel="false">

<solid android:color="@android:color/transparent" />

<stroke
    android:width="@dimen/dp_1"
    android:color="@android:color/white" />

6. Bộ chuyển đổi

class HomeOffersAdapter : RecyclerView.Adapter<HomeOffersAdapter.HomeOffersViewHolder>() {

private var list: List<ImageModel> = listOf()


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeOffersViewHolder {
    return HomeOffersViewHolder(parent)
}


override fun onBindViewHolder(holder: HomeOffersViewHolder, position: Int) {
    holder.bind(list[position])
}

fun setItem(list: List<ImageModel>) {
    this.list = list
    notifyDataSetChanged()
}

override fun getItemCount(): Int = list.size

class HomeOffersViewHolder constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {

    constructor(parent: ViewGroup) : this(
        LayoutInflater.from(parent.context).inflate(
            R.layout.pager_item,
            parent, false
        )
    )

    fun bind(imageModel: ImageModel) {
        itemView.offerImage.setImageResource(imageModel.image)
    }
}

}

7. Bố cục: pager_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">

<androidx.appcompat.widget.AppCompatImageView
    android:id="@+id/offerImage"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dp_200"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    tools:src="@drawable/offer1" />


0

Đặt ViewFlipper và viewFlipper_linear_dot_lay (Linearlayout) trên samebaseline và làm theo cách dưới đây

viewFlipper_linear_dot_lay= (LinearLayout) findViewById(R.id.dots_lay);
setupDotsOnViewPager(images_viewFlipper);
    for (int i = 0; i < images_viewFlipper.size(); i++) {
    //Add Images to ViewFlipper 
    }



private void setupDotsOnViewPager(ArrayList images_viewFlipper) {
                    images_linear = new ImageView[images_viewFlipper.size()];
                    for (int i = 0; i < images_linear.length; i++) {
                        images_linear[i] = new ImageView(this);
                        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                        params.setMargins(5, 0, 5, 0);
                        params.gravity = Gravity.BOTTOM | Gravity.CENTER;
                        images_linear[i].setLayoutParams(params);
                        images_linear[i].setImageResource(R.drawable.unselected);
                        viewFlipper_linear_dot_lay.addView(images_linear[i]);
                        viewFlipper_linear_dot_lay.bringToFront();
                    }
                }

Và OnRight & OnLeft được đặt mã dưới đây

for (int i = 0; i < images_linear.length; i++) {
 images_linear[i].setImageResource(R.drawable.unselected);
 }
images_linear[viewFlipper.getDisplayedChild()].setImageResource(R.drawable.selected);

0

Thêm phụ thuộc> Đồng bộ hóa Gradle

implementation 'com.tbuonomo.andrui:viewpagerdotsindicator:4.1.2'

Trong mã java của bạn

 dotsIndicator = (DotsIndicator) findViewById(R.id.dots_indicator3);


myViewPagerAdapter = new MyViewPagerAdapter();
        viewPager.setAdapter(myViewPagerAdapter);
        viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
        dotsIndicator.setViewPager(viewPager);

Trong bố cục của bạn

<com.tbuonomo.viewpagerdotsindicator.SpringDotsIndicator
android:id="@+id/spring_dots_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:dampingRatio="0.5"
app:dotsColor="@color/material_white"
app:dotsStrokeColor="@color/material_yellow"
app:dotsCornerRadius="2dp"
app:dotsSize="16dp"
app:dotsSpacing="6dp"
app:dotsStrokeWidth="2dp"
app:stiffness="300"
/>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.