Как создать Android View Pager с точечным индикатором?

Вероятно, многие из вас (как и я), имеют проблемы с созданиемViewPager с нижними точками, вот так:

Как вы создаете такой Android ViewPager?

 jay19 июл. 2016 г., 15:08
какого черта это понижается? вам не только разрешено отвечать на ваши собственные вопросы, этопоощряла!

Ответы на вопрос(5)

Сначала создайте макет, в котором укажите один LinerLayout для точек, которые отображаются поверх вашего View Pager.

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

    <android..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>

После этого создайте 2 рисунка

1. Не выбранный 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. Выбранный 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="#000000"/>
</shape>

После этого установите адаптер

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) {

        }
    });
}

Создайте метод 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();
    }
 amity29 авг. 2018 г., 14:40
Немного измените onPageSelect для идеальной работы, как показано ниже. Переопределите fun onPageSelected (position: Int) {for (i в 0 до ivArrayDotsPager !!. Size) {if (i! = Position) ivArrayDotsPager !! [i] .setImageDrawable (ContextCompat.getDrawable ( applicationContext, R.drawable.unselected_dot)) иначе ivArrayDotsPager !! [i] .setImageDrawable (ContextCompat.getDrawable (applicationContext, R.drawable.selected_dot))} linearLayout !!. takeToFront ()}
 eC Droid23 нояб. 2017 г., 07:55
Upvote для того, чтобы сделать это самостоятельно.
 CoolMind17 июл. 2018 г., 12:28
И чтоHomeViewPagerAdapter?

https://github.com/tommybuonomo/dotsindicator

В вашем макете XML

  <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"
      />

В вашем коде Java

dotsIndicator = (DotsIndicator) findViewById(R.id.dots_indicator);
viewPager = (ViewPager) findViewById(R.id.view_pager);
adapter = new ViewPagerAdapter();
viewPager.setAdapter(adapter);
dotsIndicator.setViewPager(viewPager);
 Shivam Kumar26 дек. 2018 г., 10:10
как автоматически прокрутить DotsIndicator
 Fat Monk31 окт. 2017 г., 22:16
Я получаюgradle ошибка, хотя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' - Как я могу это исправить?
 Fat Monk31 окт. 2017 г., 22:03
Очень прост в использовании и отлично смотрится, особенно с анимацией ... спасибо! Я, однако, должен добавитьtools:replace="android:label" кapplication тег в моемAndroidManifest.xml чтобы избавиться от ошибки, связанной с тем, что этот тег был определен дважды и вызвал сбой сборки gradle.
Решение Вопроса

ViewPager, TabLayout и 2 рисования для выбранных и стандартных точек.

Во-первых, мы должны добавитьTabLayout к нашему макету экрана, и подключите его сViewPager, Мы можем сделать это двумя способами:

ВложенныеTabLayout вViewPager
<android.support.v4.view.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</android.support.v4.view.ViewPager>

В этом случаеTabLayout будет автоматически связан сViewPager, ноTabLayout будет рядом сViewPagerне над этим.

отдельныйTabLayout
<android.support.v4.view.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

В этом случае мы можем поставитьTabLayout где угодно, но мы должны подключитьсяTabLayout сViewPager программно

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);

Как только мы создали наш макет, мы должны подготовить наши точки. Итак, мы создаем три файла:selected_dot.xml, default_dot.xml а такжеtab_selector.xml.

selected_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>

Теперь нам нужно добавить только 3 строки кодаTabLayout в нашем XML-макете.

app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
 RediOne118 окт. 2018 г., 18:02
@ Touré Holder Да
 Fat Monk31 окт. 2017 г., 16:54
Я получаю сообщение об ошибке, очень похожее на описанное вstackoverflow.com/questions/31712563/... при попытке использовать это. Решения, предложенные для связанного вопроса, также не решают проблему. Приложение компилируется и запускается нормально, в редакторе нет ошибок, но при попытке раздувать действие происходит сбой приложения.
 eC Droid23 нояб. 2017 г., 07:54
У меня только Viewpager, подскажите пожалуйста что делать.
 Parth Patel11 июл. 2018 г., 07:12
Спасибо за предоставление такого простого и надежного решения.
 Amit Singh05 июн. 2017 г., 08:56
Эй, можешь помочь мне сократить разрывы между точками?
 RediOne114 сент. 2016 г., 21:52
 RediOne118 июл. 2018 г., 11:49
@CoolMind У вас естьxmlns:app="http://schemas.android.com/apk/res-auto" поверх вашего файла макета? Если вы можете, пожалуйста, вставьте весь файл макета вpastebin.com и вставьте ссылку сюда.
 Mikkel Larsen03 июн. 2019 г., 14:06
Блестящий, работал как шарм.
 CoolMind18 июл. 2018 г., 11:52
@ RediOne1, да, у меня есть этот атрибут. Я удалилTabLayoutпотому что это не нужно. Но если вы хотите, я могу создать образец макета для вас.
 dawn06 июн. 2017 г., 17:29
не может поставить эти индикаторы в нижней части перекрытия макетаViewPager, Когда используешьLinearLayout это идет нижеViewPager и используяRelativeLayout тоже самое.
 RediOne119 июл. 2018 г., 08:23
@CoolMind Хорошо, сделай это, пожалуйста.
 Black_Zerg28 февр. 2019 г., 11:17
Спасибо! Просто нужно разместить TabLayout вне ViewPager, чтобы разместить под ViewPager
 Seven19 окт. 2017 г., 23:20
Я не знаю, правильно ли я следовал инструкциям, но мне также пришлось добавить следующее, чтобы показывать только точки с приличным интервалом между ними:app:tabMaxWidth="30dp" app:tabTextColor="@color/transparent2" app:tabSelectedTextColor="@color/transparent2" app:tabIndicatorHeight="0dp" android:layout_gravity="bottom|center"
 Jordan H24 апр. 2019 г., 18:34
Я должен был добавитьimplementation 'com.android.support:support-v4:x.x.x' в зависимости, в противном случае я получил такие ошибки, какAndroid resource linking failed attribute tabBackground (aka com.company.appname:tabBackground) not found.
 CoolMind17 июл. 2018 г., 10:51
@ RediOne1, 3 строки исключения какAGPBI: {"kind":"error","text":"error: attribute \u0027com.example:tabBackground\u0027 not found.","sources":[{"file":"C:\\Users\\user\\AndroidStudioProjects\\sample\\app\\src\\main\\res\\layout\\activity_start.xml","position":{"startLine":53}}],"original":"","tool":"AAPT"}, После удаленияapp приписывает это давит с исключениемCaused by: android.view.InflateException: Binary XML file line #54: Error inflating class android.support.design.widget.TabLayout, Я пишу в Котлине.
 Touré Holder18 окт. 2018 г., 17:28
@ RediOne1 xml может быть просто <shape> вместо <shape> в <item> в <layer-list>, верно?
 Sam24 мая 2018 г., 21:32
Я последовал вашему ответу, и все работает очень гладко, спасибо. У меня есть один вопрос, хотя, в моем приложенииTabLayout всегда в дальнем верху много чего пробовал, поставить его в низ без удачи. Я поместил его в гнездоViewPager а также отдельно. все та же проблема. Есть идеи?
 Erfan GLMPR14 сент. 2016 г., 15:49
Вам лучше поместить это в раздел документации. это помогло хотя.
 dev_mg9921 нояб. 2017 г., 08:46
Для удаления промежутка между точками app: tabPaddingStart = "@ dimension / margin_7.5" app: tabPaddingEnd = "@ dimension / margin_7.5"
 RediOne107 июн. 2017 г., 13:16
@dawnTabLayout должен быть размещен как отдельный виджет (как в примереотдельныйTabLayout, Если вы положитеTabLayout как ребенокViewPager это будет автоматически размещено нижеViewPager и не перекрывать это.
 Christopher M.24 дек. 2017 г., 17:20
Это великолепно, просто хочу, чтобы я хотел.
 Sam24 мая 2018 г., 21:48
Спасибо, я следил за этимссылка на сайт исправитьTabLayout положение на экране
 RediOne105 июн. 2017 г., 11:13
@AmitSingh Вы можете использоватьapp:tabMaxWidth в TabLayout
 RediOne117 июл. 2018 г., 08:31
@CoolMind Пожалуйста, вставьте свою ошибку.
 Maveňツ24 апр. 2019 г., 15:30
невозможно найти tabIndicatorHeight
 CoolMind16 июл. 2018 г., 16:54
После добавленияapp:tabBackground="@drawable/tab_selector" и другие, чтобы TabLayout приложение перестало компилироваться с ошибкой.

дну и ту же базовую линию и следуйте приведенному ниже

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();
                    }
                }

И OnRight & OnLeft получает размещенный ниже код

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

Ваш xml

  <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"
                    />

создать Drawable. щелкните правой кнопкой мыши на drawable -> new -> Drawable.

tab_selector.xml

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

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

Теперь есть еще два XML-файла. создайте еще два xml-файла с уважаемым именем. это индикатор селектора и невыбранный индикатор

selected_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>

unselected_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>
 CoolMind16 июл. 2018 г., 15:15
НаверноеSmartViewPager это ваш пользовательский вид.

Ваш ответ на вопрос