Android ViewPager dengan titik-titik terbawah

Jawaban:

356

Tidak perlu kode sebanyak itu.

Anda dapat melakukan semua hal ini tanpa terlalu banyak coding hanya viewpagerdengan menggunakan tablayout.

Tata Letak utama Anda:

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

Sambungkan elemen UI Anda tanpa aktivitas atau fragmen sebagai berikut:

Kode Java:

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

Itu saja, Anda baik untuk pergi.

Anda harus membuat file sumber daya xml berikut di folder 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>

Merasa malas seperti saya? Nah, semua kode di atas dikonversi menjadi perpustakaan! Penggunaan Tambahkan yang berikut di gradle Anda: implementation 'com.chabbal:slidingdotsplash:1.0.2' Tambahkan berikut ini ke aktivitas atau tata letak Fragmen Anda.

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

Buat array integer di strings.xmlmis

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

Selesai! Ekstra untuk mendengarkan perubahan halaman, gunakan tautanaddOnPageChangeListener(listener); Github .

Junaid
sumber
3
Saya sudah terbalik sebelum saya mengajukan pertanyaan, karena sudah banyak membantu saya, tapi sekarang saya berharap saya dapat apvote +2 atau +100 :) karena menambahkan onPageChangeListener bekerja dengan sempurna untuk saya! Dan hanya untuk memperjelas bagi siapa saja yang mungkin menggunakan ini, Anda perlu melakukan pembaruan Anda hanya pada panggilan balik onPageSelected, menambahkan pembaruan dalam panggilan balik onPageScrolled membuatnya berantakan, memulai pembaruan segera setelah Anda mulai menggulir, yang tidak secara visual bagus!
Mohamed Hamdaoui
1
Mengapa kita membutuhkan TabLayout?
winklerrr
14
Anda ingin menggunakan com.google.android.material.tabs.TabLayoutdalam Versi yang lebih baru
schlenger
2
Pembaruan: itu berfungsi tetapi Anda harus menggunakan komponen baru: androidx.viewpager.widget.ViewPager dan com.google.android.material.tabs.TabLayout
dreinoso
2
XML yang dapat digambar di atas terlihat aneh sampai saya berubah bentuk menjadi ring. Sepertinya cincin juga digunakan dalam pustaka slidingdotsplash bukan oval.
katie
39

Solusi buatan tangan saya:

Dalam tata letak:

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

Dan dalam Aktivitas

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
sumber
3
Mengapa menggunakan komponen berat Layouthanya untuk menaruh titik? Gunakan Viewsebagai gantinya.
Apurva
2
Saya pikir tata letak linear sehingga akan memusatkan dan mengelompokkan titik-titik.
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
sumber
18
setOnPageChangedListener()usang !! Gunakan addOnPageChangedListener()sekarang
Apurva
12
Ini sebenarnya bukan solusi yang hebat, karena Anda harus tahu persis berapa banyak halaman yang akan Anda gunakan. Segera setelah Anda menambah atau menghapus halaman, Anda dalam masalah.
FrostRocket
3
Jangan melawan kerangka kerja. Android memiliki alat untuk melakukan ini sebagai TabLayout, tidak ada alasan untuk menciptakan kembali roda.
kike
3
Sederhanakan untuk ini: 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); }
Duna
31

Saya membuat perpustakaan untuk menjawab kebutuhan akan indikator halaman di ViewPager. Perpustakaan saya berisi Tampilan yang disebut DotIndicator. Untuk menggunakan perpustakaan saya, tambahkan compile 'com.matthew-tamlin:sliding-intro-screen:3.2.0'ke file build gradle Anda.

Tampilan dapat ditambahkan ke tata letak Anda dengan menambahkan yang berikut:

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

Kode di atas secara sempurna mereplikasi fungsionalitas titik-titik pada layar beranda Peluncur Google, namun jika Anda ingin menyesuaikannya lebih lanjut maka atribut berikut dapat ditambahkan:

  • app:unselectedDotDiameterdan app:selectedDotDiameteruntuk mengatur diameter titik-titik
  • app:unselectedDotColordan app:selectedDotColoruntuk mengatur warna titik-titik
  • app:spacingBetweenDots untuk mengubah jarak antara titik-titik
  • app:dotTransitionDuration untuk mengatur waktu untuk menghidupkan perubahan dari kecil ke besar (dan kembali)

Selain itu, tampilan dapat dibuat secara terprogram menggunakan:

DotIndicator indicator = new DotIndicator(context);

Ada metode untuk memodifikasi properti, mirip dengan atribut. Untuk memperbarui indikator untuk menampilkan halaman berbeda seperti yang dipilih, cukup panggil metode indicator.setSelectedItem(int, true)dari dalamViewPager.OnPageChangeListener.onPageSelected(int) .

Berikut ini contoh penggunaannya:

masukkan deskripsi gambar di sini

Jika Anda tertarik, perpustakaan sebenarnya dirancang untuk membuat layar intro seperti yang ditunjukkan pada gif di atas.

Sumber Github tersedia di sini: https://github.com/MatthewTamlin/SlidingIntroScreen

Helios
sumber
Mendapat kesalahan di indicator.setSelectedItem (posisi, true); IndexOutOfBoundsException
Dixit Panchal
Versi yang mana? Saya pikir saya memperbaikinya di 3.0.1, juga apa nilai Anda untuk indicator.size () dan posisi?
Helios
Perpustakaan yang bagus! Namun, apakah ada cara yang lebih elegan untuk memperbarui Item yang dipilih dan angka dari Item pada saat yang sama? Bergantung pada mana yang lebih besar, urutannya berubah, jika tidak, Anda akan melempar pengecualian IndexOutOfBounds. Lihat intinya .
vsp
@vsp DotIndicator mengimplementasikan antarmuka SelectionIndicator, yang berarti jika memiliki dua metode berguna yang dapat menyelesaikan masalah Anda: int getNumberOfItems()dan void setNumberOfItems(). Daripada menangkap pengecualian, Anda dapat melakukan sesuatu seperti gist.github.com/MatthewTamlin/761c7338d271af29526edc7859480aef .
Helios
Bagi siapa pun yang tidak mengikuti percakapan inti, sebenarnya ada bug yang sekarang telah diperbaiki. 3.0.2 adalah versi terbaru saat ini.
Helios
18

ViewPagerIndicator belum diperbarui sejak 2012 dan mendapat beberapa bug yang tidak pernah diperbaiki.

Saya akhirnya menemukan alternatif dengan perpustakaan ringan ini yang menampilkan titik-titik bagus untuk viewpager , di sini adalah tautannya:

https://github.com/ongakuer/CircleIndicator

Mudah diimplementasikan!

Yoann Hercouet
sumber
16

Saya berpikir untuk memposting solusi yang lebih sederhana untuk masalah di atas dan nomor indikator dapat diubah secara dinamis dengan hanya mengubah satu nilai variabel dotCounts=xyang saya lakukan seperti ini.

1) Buat file xml di folder yang dapat digambar untuk indikator yang dipilih halaman bernama "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) Buat satu file xml lagi untuk indikator tidak dipilih bernama "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) Sekarang tambahkan tambahkan bagian kode ini di tempat Anda ingin menampilkan indikator untuk ex viewPagerdi bawah ini dalam file Layout XML Anda.

 <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) Tambahkan fungsi ini di atas file file aktivitas Anda di mana tata letak Anda meningkat atau file xml di atas terkait

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) Akhirnya dalam metode onCreate Anda tambahkan kode berikut untuk referensi tata letak Anda dan menangani posisi yang dipilih halaman

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

Anda dapat mencoba perpustakaan Jake Wharton - https://github.com/JakeWharton/Android-ViewPagerIndicator

Joel Fernandes
sumber
Bagaimana saya bisa menambahkan titik, bukan tab (seperti peluncur Nexus 5)?
Kfir Guy
@KfirGuy Mereka disebut sebagai indikator. Anda dapat melakukannya menggunakan perpustakaan yang saya sebutkan di atas. Anda juga dapat melihatnya beraksi di sini - play.google.com/store/apps/…
Joel Fernandes
@ JoelFernandes sepertinya aplikasi itu tidak tersedia di semua negara
34m0
9

Berikut ini adalah solusi yang saya usulkan.

  • Karena kita perlu menunjukkan hanya beberapa gambar dalam tampilan pager, jadi hindari penggunaan fragmen yang rumit.
    • Diimplementasikan indikator halaman tampilan (titik-titik bawah tanpa perpustakaan atau plugin tambahan)
    • Pada sentuhan indikator tampilan halaman (titik-titik) juga navigasi halaman sedang terjadi.
    • Tolong jangan lupa untuk menambahkan gambar Anda sendiri di sumber daya.
    • Jangan ragu untuk berkomentar dan memperbaikinya.

A) Berikut ini adalah activity_main.xml saya

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

gambar pertama

masukkan deskripsi gambar di sini

Ajit
sumber
saya menggunakan ini tetapi pada titik-titik gulir viewpager tidak berubah
Aditya Vyas-Lakhan
1
ini jawaban terbaik
Sandeep Londhe
1

Jika ada yang ingin membuat viewPagerthumbnail dengan indikator, menggunakan pustaka ini bisa menjadi pilihan: ThumbIndicator untuk viewPager yang berfungsi juga dengan tautan gambar sebagai sumber.

Mahdi Moqadasi
sumber
0

Inilah cara saya melakukan ini, agak mirip dengan solusi di atas. Pastikan Anda memanggil loadDots () metode setelah semua gambar di-download .

    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
sumber