Android ViewPager с нижними точками

183

Я хочу добавить 3 нижние точки в мой ViewPager, вот так.

3 нижних точки 3 нижних точки 3 нижних точки

Я использую FragmentActivity и поддерживаю библиотеку ViewPager.

Кфир Гай
источник
3
Мне нужно добавить точки, а не вкладки (например, Nexus 5 Launcher).
Кфир Гай
1
Проверьте мое решение: stackoverflow.com/a/38459310/4631935
RediOne1

Ответы:

356

Не нужно много кода.

Вы можете делать все это без особого кодирования, используя только viewpagerс tablayout.

Ваш основной макет:

<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="wrap_content">

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

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

Подключите ваши неактивные элементы интерфейса или фрагмент следующим образом:

Java-код:

mImageViewPager = (ViewPager) findViewById(R.id.pager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabDots);
tabLayout.setupWithViewPager(mImageViewPager, true);

Вот и все, вы хорошо идти.

Вам нужно будет создать следующий файл ресурсов xml в папке drawable .

tab_indicator_selected.xml

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

tab_indicator_default.xml

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

tab_selector.xml

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

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

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

Чувствуешь себя таким же ленивым, как и я? Что ж, весь приведенный выше код преобразуется в библиотеку! Использование Добавьте следующее в ваш gradle: implementation 'com.chabbal:slidingdotsplash:1.0.2' Добавьте следующее в ваш макет Activity или Fragment.

<com.chabbal.slidingdotsplash.SlidingSplashView
        android:id="@+id/splash"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:imageResources="@array/img_id_arr"/>

Создайте целочисленный массив, strings.xmlнапример, в

<integer-array name="img_id_arr">
   <item>@drawable/img1</item>
   <item>@drawable/img2</item>
   <item>@drawable/img3</item>
   <item>@drawable/img4</item>
</integer-array>

Готово! Дополнительно , чтобы прослушать изменения страницы, используйте ссылкуaddOnPageChangeListener(listener); Github .

Junaid
источник
3
Я уже проголосовал до того, как задал вопрос, потому что это мне уже очень помогло, но теперь я хочу, чтобы я мог добавить +2 или +100 :), потому что добавление onPageChangeListener отлично сработало для меня! И просто для того, чтобы всем было понятно, кто может это использовать, вам нужно делать обновления только для обратного вызова onPageSelected. Добавление обновления в обратный вызов onPageScrolled делает его беспорядочным, оно запускает обновление, как только вы начинаете прокручивать, а это не так. визуально хорошо!
Мохамед Хамдауи
1
Зачем нам нужен TabLayout?
winklerrr
14
Вы хотите использовать com.google.android.material.tabs.TabLayoutв более новых версиях
schlenger
2
Обновление: это работает, но вы должны использовать новые компоненты: androidx.viewpager.widget.ViewPager и com.google.android.material.tabs.TabLayout
dreinoso
2
Вышеприведенный отрисовываемый XML выглядит странно, пока я не изменил форму на ring. Похоже, что кольцо также используется в библиотеке slidedotsplash вместо овального.
Кэти
39

Мое решение ручной работы:

В макете:

<LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/dots"
        />

И в деятельности

private final static int NUM_PAGES = 5;
private ViewPager mViewPager;
private List<ImageView> dots;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...
    addDots();
}

public void addDots() {
    dots = new ArrayList<>();
    LinearLayout dotsLayout = (LinearLayout)findViewById(R.id.dots);

    for(int i = 0; i < NUM_PAGES; i++) {
        ImageView dot = new ImageView(this);
        dot.setImageDrawable(getResources().getDrawable(R.drawable.pager_dot_not_selected));

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        dotsLayout.addView(dot, params);

        dots.add(dot);
    }

    mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            selectDot(position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });
}

public void selectDot(int idx) {
    Resources res = getResources();
    for(int i = 0; i < NUM_PAGES; i++) {
        int drawableId = (i==idx)?(R.drawable.pager_dot_selected):(R.drawable.pager_dot_not_selected);
        Drawable drawable = res.getDrawable(drawableId);
        dots.get(i).setImageDrawable(drawable);
    }
}
Марин Шаламанов
источник
3
Зачем использовать тяжелый компонент Layoutпросто чтобы поставить точку? Используйте Viewвместо этого.
Апурва
2
Я думаю, что линейная схема такова, что она будет центрировать и группировать точки.
ShawnV
38
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {

                switch (position) {
    case 0:
        img_page1.setImageResource(R.drawable.dot_selected);
        img_page2.setImageResource(R.drawable.dot);
        img_page3.setImageResource(R.drawable.dot);
        img_page4.setImageResource(R.drawable.dot);
        break;

    case 1:
        img_page1.setImageResource(R.drawable.dot);
        img_page2.setImageResource(R.drawable.dot_selected);
        img_page3.setImageResource(R.drawable.dot);
        img_page4.setImageResource(R.drawable.dot);
        break;

    case 2:
        img_page1.setImageResource(R.drawable.dot);
        img_page2.setImageResource(R.drawable.dot);
        img_page3.setImageResource(R.drawable.dot_selected);
        img_page4.setImageResource(R.drawable.dot);
        break;

    case 3:
        img_page1.setImageResource(R.drawable.dot);
        img_page2.setImageResource(R.drawable.dot);
        img_page3.setImageResource(R.drawable.dot);
        img_page4.setImageResource(R.drawable.dot_selected);
        break;

    default:
        break;
    }


            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {

            }
        });
Капил Тадани
источник
18
setOnPageChangedListener()осуждается !! Используйте addOnPageChangedListener()сейчас.
Апурва
12
Это не очень хорошее решение, так как вы должны точно знать, сколько страниц вы будете использовать. Как только вы добавите или удалите страницу, у вас возникнут проблемы.
FrostRocket
3
Не борись за рамки. В Android есть инструменты для этого, такие как TabLayout, поэтому нет причин изобретать велосипед.
kike
3
Упростите это: private void setDotSelection (int index) {dot1.setImageResource (index == 0? R.drawable.circle_selected: R.drawable.circle); dot2.setImageResource (index == 1? R.drawable.circle_selected: R.drawable.circle); dot3.setImageResource (index == 2? R.drawable.circle_selected: R.drawable.circle); dot4.setImageResource (index == 3? R.drawable.circle_selected: R.drawable.circle); dot5.setImageResource (index == 4? R.drawable.circle_selected: R.drawable.circle); }
Дуна
31

Я создал библиотеку, чтобы удовлетворить потребность в индикаторе страницы в ViewPager. Моя библиотека содержит представление под названием DotIndicator. Чтобы использовать мою библиотеку, добавьтеcompile 'com.matthew-tamlin:sliding-intro-screen:3.2.0' в свой файл сборки Gradle.

Вид можно добавить в макет, добавив следующее:

    <com.matthewtamlin.sliding_intro_screen_library.indicators.DotIndicator
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:numberOfDots=YOUR_INT_HERE
            app:selectedDotIndex=YOUR_INT_HERE/>

Приведенный выше код прекрасно повторяет функциональность точек на домашнем экране Google Launcher, однако, если вы хотите дополнительно настроить его, можно добавить следующие атрибуты:

  • app:unselectedDotDiameterи app:selectedDotDiameterустановить диаметры точек
  • app:unselectedDotColorи app:selectedDotColorустановить цвета точек
  • app:spacingBetweenDots изменить расстояние между точками
  • app:dotTransitionDuration установить время для анимации изменения с малого на большое (и обратно)

Кроме того, представление может быть создано программно с помощью:

DotIndicator indicator = new DotIndicator(context);

Существуют методы для изменения свойств, аналогичных атрибутам. Чтобы обновить индикатор для отображения другой выбранной страницы, просто вызовите метод indicator.setSelectedItem(int, true)изнутриViewPager.OnPageChangeListener.onPageSelected(int) .

Вот пример его использования:

введите описание изображения здесь

Если вам интересно, библиотека на самом деле была спроектирована так, чтобы создавать заставки, подобные показанному на рисунке выше.

Источник Github доступен здесь: https://github.com/MatthewTamlin/SlidingIntroScreen

Helios
источник
Ошибка в Indicator.setSelectedItem (позиция, истина); IndexOutOfBoundsException
Диксит Панчал
Какая версия? Я думал, что я исправил это в 3.0.1, также, каковы были ваши значения для index.size () и позиции?
Гелиос
Отличная библиотека! Однако, есть ли более элегантный способ обновить selectedItem и numberOfItems одновременно? В зависимости от того, какой из них больше, порядок меняется, в противном случае вы генерируете исключение IndexOutOfBounds. Смотрите эту суть .
vsp
@vsp DotIndicator реализует интерфейс SelectionIndicator, что означает, что есть два полезных метода, которые могут решить вашу проблему: int getNumberOfItems()и void setNumberOfItems(). Вместо того, чтобы поймать исключение, вы можете сделать что-то вроде этого gist.github.com/MatthewTamlin/761c7338d271af29526edc7859480aef .
Гелиос
Для тех, кто не следил за разговором о сути, на самом деле была ошибка, которая была исправлена. 3.0.2 является последней версией на данный момент.
Гелиос
18

ViewPagerIndicator не обновлялся с 2012 года и получил несколько ошибок, которые никогда не были исправлены.

Я наконец нашел альтернативу с этой легкой библиотекой, которая отображает хорошие точки для viewpager , вот ссылка:

https://github.com/ongakuer/CircleIndicator

Легко реализовать!

Йоанн Херкуэ
источник
16

Я подумал о том, чтобы опубликовать более простое решение для вышеупомянутой проблемы, и номера индикаторов можно динамически изменять, изменяя только одно значение переменной, dotCounts=xчто я и сделал так.

1) Создайте XML-файл в папке для рисования для выбранного индикатора страницы с именем «item_selected».

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

2) Создайте еще один XML-файл для невыбранного индикатора с именем "item_unselected"

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" android:useLevel="true"
    android:dither="true">

    <size android:height="8dp" android:width="8dp"/>

    <solid android:color="@color/image_item_unselected_for_dots"/>
</shape>

3) Теперь добавьте эту часть кода в то место, где вы хотите отобразить индикаторы для ex ниже viewPagerв вашем файле Layout XML.

 <RelativeLayout
        android:id="@+id/viewPagerIndicator"
        android:layout_width="match_parent"
        android:layout_below="@+id/banner_pager"
        android:layout_height="wrap_content"
        android:gravity="center">

        <LinearLayout
            android:id="@+id/viewPagerCountDots"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:orientation="horizontal" />
        </RelativeLayout>

4) Добавьте эту функцию поверх файла вашего файла активности, где ваш макет завышен или вышеупомянутый файл XML связан с

private int dotsCount=5;    //No of tabs or images
private ImageView[] dots;
LinearLayout linearLayout;

private void drawPageSelectionIndicators(int mPosition){
    if(linearLayout!=null) {
        linearLayout.removeAllViews();
    }
    linearLayout=(LinearLayout)findViewById(R.id.viewPagerCountDots);
    dots = new ImageView[dotsCount];
    for (int i = 0; i < dotsCount; i++) {
        dots[i] = new ImageView(context);
        if(i==mPosition)
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.item_selected));
        else
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.item_unselected));

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );

        params.setMargins(4, 0, 4, 0);
        linearLayout.addView(dots[i], params);
    }
}

5) Наконец, в вашем методе onCreate добавьте следующий код, чтобы ссылаться на ваш макет и обрабатывать выбранные позиции на странице.

drawPageSelectionIndicators(0);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        drawPageSelectionIndicators(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
});
Локанатх
источник
13

Вы можете попробовать библиотеку Джейка Уортона - https://github.com/JakeWharton/Android-ViewPagerIndicator

Джоэл Фернандес
источник
Как добавить точки, а не вкладки (например, панель запуска Nexus 5)?
Кфир Гай
@KfirGuy Их называют индикаторами. Вы можете сделать это с помощью библиотеки, которую я упомянул выше. Кроме того, вы можете увидеть его в действии здесь - play.google.com/store/apps/…
Джоэл Фернандес
@JoelFernandes похоже, что это приложение доступно не во всех странах
34m0
9

Следующее - мое предлагаемое решение.

  • Поскольку нам нужно показывать только некоторые изображения в пейджерах, мы избегаем громоздкого использования фрагментов.
    • Реализованы индикаторы просмотра страницы (нижние точки без какой-либо дополнительной библиотеки или плагина)
    • При касании индикаторов страницы просмотра (точек) также происходит навигация по странице.
    • Пожалуйста, не забудьте добавить свои собственные изображения в ресурсы.
    • Не стесняйтесь комментировать и улучшать его.

А) Следующее - это мой activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="schneider.carouseladventure.MainActivity">

    <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/viewpager"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RelativeLayout
        android:id="@+id/viewPagerIndicator"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:layout_alignParentBottom="true"
        android:layout_marginTop="5dp"
        android:gravity="center">

        <LinearLayout
            android:id="@+id/viewPagerCountDots"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:orientation="horizontal" />

    </RelativeLayout>


</RelativeLayout>

Б) pager_item.xml

<?xml version="1.0" encoding="utf-8"?>

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

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/imageView" />
</LinearLayout>

C) MainActivity.java

import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener, View.OnClickListener {

    int[] mResources = {R.drawable.nature1, R.drawable.nature2, R.drawable.nature3, R.drawable.nature4,
            R.drawable.nature5, R.drawable.nature6
    };

    ViewPager mViewPager;
    private CustomPagerAdapter mAdapter;
    private LinearLayout pager_indicator;
    private int dotsCount;
    private ImageView[] dots;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        pager_indicator = (LinearLayout) findViewById(R.id.viewPagerCountDots);
        mAdapter = new CustomPagerAdapter(this, mResources);
        mViewPager.setAdapter(mAdapter);
        mViewPager.setCurrentItem(0);
        mViewPager.setOnPageChangeListener(this);

        setPageViewIndicator();

    }

    private void setPageViewIndicator() {

        Log.d("###setPageViewIndicator", " : called");
        dotsCount = mAdapter.getCount();
        dots = new ImageView[dotsCount];

        for (int i = 0; i < dotsCount; i++) {
            dots[i] = new ImageView(this);
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));

            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
            );

            params.setMargins(4, 0, 4, 0);

            final int presentPosition = i;
            dots[presentPosition].setOnTouchListener(new View.OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mViewPager.setCurrentItem(presentPosition);
                    return true;
                }

            });


            pager_indicator.addView(dots[i], params);
        }

        dots[0].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

        Log.d("###onPageSelected, pos ", String.valueOf(position));
        for (int i = 0; i < dotsCount; i++) {
            dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot));
        }

        dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot));

        if (position + 1 == dotsCount) {

        } else {

        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

D) CustomPagerAdapter.java

 import android.content.Context;
    import android.support.v4.view.PagerAdapter;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.LinearLayout;

    public class CustomPagerAdapter extends PagerAdapter {
        private Context mContext;
        LayoutInflater mLayoutInflater;
        private int[] mResources;

        public CustomPagerAdapter(Context context, int[] resources) {
            mContext = context;
            mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mResources = resources;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            View itemView = mLayoutInflater.inflate(R.layout.pager_item,container,false);
            ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
            imageView.setImageResource(mResources[position]);
           /* LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(950, 950);
            imageView.setLayoutParams(layoutParams);*/
            container.addView(itemView);
            return itemView;
        }

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

        @Override
        public int getCount() {
            return mResources.length;
        }

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

E) selecteditem_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" android:useLevel="true"
    android:dither="true">

    <size android:height="12dip" android:width="12dip"/>

    <solid android:color="#7e7e7e"/>
</shape>

F) nonselecteditem_dot.xml

 <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval" android:useLevel="true"
        android:dither="true">        
        <size android:height="12dip" android:width="12dip"/>        
        <solid android:color="#d3d3d3"/>
    </shape>

первое изображение

введите описание изображения здесь

Ажит
источник
Я использовал это, но на прокрутке виджета точки не меняются
Адитья Вьяс-
1
это лучший ответ.
Сандип Лондэ
1

Если кто-то хочет построить viewPagerминиатюры в качестве индикаторов, можно использовать эту библиотеку: ThumbIndicator для viewPager, который также работает с ссылками на изображения в качестве ресурсов.

Махди Мокадаси
источник
0

Вот как я это сделал, чем-то похожий на решения выше. Просто убедитесь , что вы называете () loadDots методом после того, как все изображения будут загружены .

    private int dotsCount;
    private TextView dotsTextView[];

    private void setupAdapter() {
        adapter = new SomeAdapter(getContext(), images);
        viewPager.setAdapter(adapter);
        viewPager.setCurrentItem(0);
        viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
    }

    private final ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

        @Override
        public void onPageSelected(int position) {
            for (int i = 0; i < dotsCount; i++)
                dotsTextView[i].setTextColor(Color.GRAY);

            dotsTextView[position].setTextColor(Color.WHITE);
        }

        @Override
        public void onPageScrollStateChanged(int state) {}
    };

    protected void loadDots() {
        dotsCount = adapter.getCount();
        dotsTextView = new TextView[dotsCount];
        for (int i = 0; i < dotsCount; i++) {
            dotsTextView[i] = new TextView(getContext());
            dotsTextView[i].setText(R.string.dot);
            dotsTextView[i].setTextSize(45);
            dotsTextView[i].setTypeface(null, Typeface.BOLD);
            dotsTextView[i].setTextColor(android.graphics.Color.GRAY);
            mDotsLayout.addView(dotsTextView[i]);
        }
        dotsTextView[0].setTextColor(Color.WHITE);
    }

XML

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:background="#00000000"/>


    <ImageView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/introImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:id="@+id/image_count"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        android:gravity="center|bottom"
        android:orientation="horizontal"/>
</FrameLayout>
r3dm4n
источник