ViewPager Android avec les points du bas

Réponses:

356

Pas besoin de tant de code.

Vous pouvez faire tout cela sans trop coder en utilisant uniquement viewpageravec tablayout.

Votre mise en page principale:

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

Connectez l'inactivité ou le fragment de vos éléments d'interface utilisateur comme suit:

Code Java:

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

Voilà, vous êtes prêt à partir.

Vous devrez créer le fichier de ressources xml suivant dans le dossier 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>

Vous vous sentez aussi paresseux que moi? Eh bien, tout le code ci-dessus est converti en bibliothèque! Utilisation Ajoutez ce qui suit dans votre note: implementation 'com.chabbal:slidingdotsplash:1.0.2' Ajoutez ce qui suit à votre disposition Activité ou 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"/>

Créer un tableau d'entiers par strings.xmlexemple

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

Terminé! Extra pour écouter les changements de page, utilisez le lienaddOnPageChangeListener(listener); Github .

Junaid
la source
3
J'avais déjà voté avant de poser la question, car cela m'a déjà beaucoup aidé, mais maintenant j'aimerais pouvoir apvoter +2 ou +100 :) parce que l'ajout de onPageChangeListener a parfaitement fonctionné pour moi! Et juste pour que tout le monde puisse l'utiliser, vous devez effectuer vos mises à jour uniquement sur le rappel onPageSelected, l'ajout de la mise à jour dans le rappel onPageScrolled le rend compliqué, il démarre la mise à jour dès que vous commencez à faire défiler, ce qui n'est pas visuellement bien!
Mohamed Hamdaoui
1
Pourquoi avons-nous besoin d'un TabLayout?
winklerrr
14
Vous souhaitez utiliser com.google.android.material.tabs.TabLayoutdans les nouvelles versions
schlenger
2
Mise à jour: cela fonctionne mais vous devriez utiliser de nouveaux composants: androidx.viewpager.widget.ViewPager et com.google.android.material.tabs.TabLayout
dreinoso
2
Le XML dessinable ci-dessus semble étrange jusqu'à ce que je change de forme en ring. On dirait que l'anneau est également utilisé dans la bibliothèque glissantdotsplash au lieu de l'ovale.
katie
39

Ma solution artisanale:

Dans la mise en page:

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

Et dans l'activité

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);
    }
}
Marin Shalamanov
la source
3
Pourquoi utiliser un composant lourd Layoutjuste pour mettre un point? Utilisez Viewplutôt.
Apurva
2
Je pense que la disposition linéaire est telle qu'elle centrera et regroupera les points.
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) {

            }
        });
kapil thadani
la source
18
setOnPageChangedListener()obsolète !! Utilisez addOnPageChangedListener()maintenant.
Apurva
12
Ce n'est pas vraiment une excellente solution, car vous devez savoir exactement combien de pages vous allez utiliser. Dès que vous ajoutez ou supprimez une page, vous êtes en difficulté.
FrostRocket
3
Ne combattez pas le cadre. Android a des outils pour faire cela comme TabLayout, il n'y a aucune raison de réinventer la roue.
kike
3
Simplifiez-vous ceci: private void setDotSelection (index int) {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); }
Duna
31

J'ai créé une bibliothèque pour répondre au besoin d'un indicateur de page dans un ViewPager. Ma bibliothèque contient une vue appelée DotIndicator. Pour utiliser ma bibliothèque, ajoutez compile 'com.matthew-tamlin:sliding-intro-screen:3.2.0'à votre fichier de construction gradle.

La vue peut être ajoutée à votre mise en page en ajoutant les éléments suivants:

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

Le code ci-dessus reproduit parfaitement la fonctionnalité des points sur l'écran d'accueil de Google Launcher, mais si vous souhaitez le personnaliser davantage, les attributs suivants peuvent être ajoutés:

  • app:unselectedDotDiameteret app:selectedDotDiameterpour régler les diamètres des points
  • app:unselectedDotColoret app:selectedDotColorpour définir les couleurs des points
  • app:spacingBetweenDots pour changer la distance entre les points
  • app:dotTransitionDuration pour définir l'heure pour animer le changement de petit à grand (et inversement)

De plus, la vue peut être créée par programme en utilisant:

DotIndicator indicator = new DotIndicator(context);

Des méthodes existent pour modifier les propriétés, similaires aux attributs. Pour mettre à jour l'indicateur pour afficher une page différente comme sélectionné, il suffit d'appeler la méthode indicator.setSelectedItem(int, true)de l'intérieurViewPager.OnPageChangeListener.onPageSelected(int) .

En voici un exemple en cours d'utilisation:

entrez la description de l'image ici

Si vous êtes intéressé, la bibliothèque a en fait été conçue pour créer des écrans d'introduction comme celui montré dans le gif ci-dessus.

Source Github disponible ici: https://github.com/MatthewTamlin/SlidingIntroScreen

Hélios
la source
Erreur obtenue à l'indicateur.setSelectedItem (position, true); IndexOutOfBoundsException
Dixit Panchal
Quelle version? Je pensais avoir corrigé cela dans la version 3.0.1, quelles étaient vos valeurs pour indicateur.size () et position?
Helios le
Grande bibliothèque! Cependant, y a-t-il un moyen plus élégant de mettre à jour selectedItem et numberOfItems en même temps? En fonction de celui qui est le plus grand, l'ordre change, sinon vous lancez une exception IndexOutOfBounds. Voir l'essentiel .
vsp
@vsp DotIndicator implémente l'interface SelectionIndicator, ce qui signifie que si a deux méthodes utiles qui peuvent résoudre votre problème: int getNumberOfItems()et void setNumberOfItems(). Plutôt que d'attraper l'exception, vous pouvez faire quelque chose comme ceci: gist.github.com/MatthewTamlin/761c7338d271af29526edc7859480aef .
Helios
Pour quiconque ne suit pas l'essentiel de la conversation, il y avait en fait un bogue qui a maintenant été corrigé. 3.0.2 est la dernière version actuellement.
Helios
18

ViewPagerIndicator n'a pas été mis à jour depuis 2012 et a reçu plusieurs bogues qui n'ont jamais été corrigés.

J'ai enfin trouvé une alternative avec cette bibliothèque de lumière qui affiche de jolis points pour le viewpager , voici le lien:

https://github.com/ongakuer/CircleIndicator

Facile à mettre en œuvre!

Yoann Hercouet
la source
16

J'ai pensé à publier une solution plus simple pour le problème ci-dessus et les numéros des indicateurs peuvent être modifiés dynamiquement en ne changeant qu'une seule valeur de variable dotCounts=x ce que j'ai fait va comme ceci.

1) Créez un fichier xml dans un dossier pouvant être dessiné pour l'indicateur de sélection de page nommé "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) Créez un autre fichier xml pour l'indicateur non sélectionné nommé "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) Ajoutez maintenant cette partie du code à l'endroit où vous souhaitez afficher les indicateurs par ex ci-dessous viewPagerdans votre fichier 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) Ajoutez cette fonction au-dessus de votre fichier d'activité où votre mise en page est gonflée ou le fichier xml ci-dessus est lié à

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) Enfin, dans votre méthode onCreate, ajoutez le code suivant pour référencer votre mise en page et gérer les positions des pages sélectionnées

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) {
    }
});
Lokanath
la source
13

Vous pouvez essayer la bibliothèque de Jake Wharton - https://github.com/JakeWharton/Android-ViewPagerIndicator

Joël Fernandes
la source
Comment puis-je ajouter des points, pas des onglets (comme le lanceur Nexus 5)?
Kfir Guy
@KfirGuy Ils sont appelés indicateurs. Vous pouvez le faire en utilisant la bibliothèque que j'ai mentionnée ci-dessus. Vous pouvez également le voir en action ici - play.google.com/store/apps/…
Joel Fernandes
@JoelFernandes semble que cette application n'est pas disponible dans tous les pays
34m0
9

Voici ma solution proposée.

  • Comme nous n'avons besoin de montrer que certaines images dans les pagers de vue, nous avons donc évité l'utilisation fastidieuse de fragments.
    • Implémentation des indicateurs de page de vue (les points du bas sans bibliothèque ou plugin supplémentaire)
    • Au toucher des indicateurs de page d'affichage (les points), la navigation dans la page se produit également.
    • N'oubliez pas d 'ajouter vos propres images dans les ressources.
    • N'hésitez pas à le commenter et à l'améliorer.

A) Voici mon 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>

B) 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) non sélectionnéitem_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>

première image

entrez la description de l'image ici

Ajit
la source
Je l'ai utilisé mais sur le viewpager, les points de défilement ne changent pas
Aditya Vyas-Lakhan
1
C'est la meilleure réponse.
Sandeep Londhe
1

Si quelqu'un veut créer un viewPageravec des vignettes comme indicateurs, utiliser cette bibliothèque pourrait être une option: ThumbIndicator pour viewPager qui fonctionne également avec des liens d'images comme ressources.

Mahdi Moqadasi
la source
0

Voici comment j'ai fait cela, un peu similaire aux solutions ci-dessus. Assurez-vous simplement d'appeler la méthode loadDots () une fois toutes les images téléchargées .

    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
la source