Android does not have a “Dot Page Indicator” similar to most launchers or some apps where when you swipe between multiple pages, it indicates you on which page you are currently on, out of the available pages.

For this reason I created a simple tutorial to create something similar to the above needs but using radio buttons. There are so many custom components which are out there, which you can use for this purpose, but if you are someone who like to create a similar looking control by only using native components, then this tutorial is for you.

dot page screenshot

Let’s create a blank android studio project and add an empty activity. This will be our placeholder.

Add the following XML to the your placeholder activity layout. The parent layout can be anything but I’m using a linear layout for my desired style.

XML Code

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.joeldroid.dotpageindicator.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:gravity="center_horizontal"
        android:paddingBottom="3dp"
        android:background="@color/colorPrimary">

        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/helpRadioGroup">

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/radioPage1"
                android:buttonTint="@color/white"
                android:clickable="false"
                android:checked="true" />

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/radioPage2"
                android:clickable="false"
                android:buttonTint="@color/white"/>

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/radioPage3"
                android:clickable="false"
                android:buttonTint="@color/white"/>
        </RadioGroup>
    </LinearLayout>

    <android.support.v4.view.ViewPager android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white" />
</LinearLayout>

Explanation

Linear Layout orientations - The parent Linear layout orientation must be set to vertical and the nested one which contains the radio buttons must have the orientation to horizontal.

Radiogroup - This is used to group all the buttons so that only one button is clicked within the group at any given time.

android:buttonTint - This determines the color of the radio button but sadly only works in API 21 and above.

Let’s add the Activity code

Let’s create variables to assign out UI components

RadioGroup radioGroup;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;

Now let’s assign these variables on onCreate method and bind to listeners

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

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    radioGroup = (RadioGroup) findViewById(R.id.helpRadioGroup);

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

        }

        @Override
        public void onPageSelected(int position) {
            switch (position) {
                case 0:
                    radioGroup.check(R.id.radioPage1);
                    break;
                case 1:
                    radioGroup.check(R.id.radioPage2);
                    break;
                case 2:
                    radioGroup.check(R.id.radioPage3);
                    break;
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

    mViewPager.setAdapter(mSectionsPagerAdapter);
}

Now let’s write the pager adapter. If we are not going to use this adapter anywhere else lets define it as a private class.

private class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        switch (position) {
            case 0:
                return new Page1Fragment();
            case 1:
                return new Page2Fragment();
            case 2:
                return new Page3Fragment();
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }
}

Now you will have some compilation errors as Page1Fragment, Page2Fragment and Page3Fragment are not defined. Not to worry we will define them now.

Fragments

Lets create fragments that can be loaded as pages, for demo purposes, let’s create 3 pages.

XML Code

<FrameLayout 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"
    tools:context="com.joeldroid.dotpageindicator.Page1Fragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:text="Page 1"
        android:textSize="20dp"/>
</FrameLayout>

Fragment Code

public class Page1Fragment extends Fragment {
    Context context;

    public Page1Fragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        context = getActivity().getApplicationContext();
        // Inflate the layout for this fragment
        View parentView = inflater.inflate(R.layout.fragment_page1, container, false);
        return parentView;
    }
}

rinse and repeat 2 more times for Page 2 and Page 3 make sure you name the classes as per the names given in the Pager adapter. That’s it, you should end up with a dot page indicator similar to the one demoed in at the start of the article. If you have any questions or clarifications, Please leave your comments below.

Get Source


Joel Jeyachandran

Interesting stuff in my life!