Android

Android ViewPager2 Example With Static Content

Google+ Pinterest LinkedIn Tumblr

Intro screens or walkthrough is the most commonly used UI for displaying the info of what the app does at the start. So, for the purpose of this, we can simply use the Android ViewPager2. It mostly used with the dots indicator and provides the ability to show different info images or with different fragments.

Scenario: Previously I was working on an android app where I need to add intro screens without adding any fragments and fix (static) content on a screen with only image changes inside the screen.

I remember searching online for a couple of days to develop something as simple as this using android ViewPager2 for the first time. So, I thought this article might be helpful for someone like me who is just starting out in Android.

For those of you, who would like to go to the sample app directly, here is the link.

Step1: Adding the Android ViewPager2 Dependency

To use ViewPager2, add the following androidx dependency inside the application build.gradle file.

dependencies {
    implementation "androidx.viewpager2:viewpager2:$version"
}

Step2: Adding the ViewPager2 inside the XML

Our journey begins with lying some foundational work of an XMl layout.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="match_parent">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/introScreenViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:orientation="vertical">

        <spartons.com.developermeetdeveloper.customViews.MyCircleImageView 
            android:id="@+id/splashScreenCenterImageView"
            android:layout_width="180dp"
            android:layout_height="180dp"
            android:layout_gravity="center" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:gravity="center"
            android:text="Welcome !"
            android:textAppearance="?textAppearanceHeadline4"
            android:textColor="?colorOnSurface" />

        <TextView
            android:id="@+id/splashScreenSubtitleTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Welcome to the world most beautiful and copy pasta app made by mighty Ahsen Saeed."
            android:textAppearance="?textAppearanceSubtitle2" />

    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="10dp"
        android:orientation="horizontal">

        <com.tbuonomo.viewpagerdotsindicator.WormDotsIndicator
            android:id="@+id/wormIndicator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal|center_vertical"
            app:dotsColor="@color/color_primary"
            app:dotsSize="10dp"
            app:dotsSpacing="2dp"
            app:dotsStrokeWidth="1dp" />

        <TextView
            android:id="@+id/splashScreenLogInButton"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="?attr/actionBarItemBackground"
            android:layout_gravity="end"
            android:text="@string/log_in"
            android:textAppearance="?textAppearanceBody1" />

    </FrameLayout>

</FrameLayout>

Things to highlight in the above code:

  • Adding the ViewPager2 for swiping the images on a single screen.
  • The MyCircleImageView is my custom class for showing the circle image. You can get the class from the complete code.
  • The WormDotsIndicator is to represent the ViewPager dots indicator. The class exists in this GitHub library. It supports both ViewPager and ViewPager2.

Step3: Setting-up Intro Activity

Now that the XML part is done, let us extract the introScreenViewPager and set an adapter on it.

class IntroScreenActivity: AppCompatActivity() {

    private companion object {
        private val centeredImageResources = mutableListOf(   // 1
            R.drawable.first_background_image,
            R.drawable.second_background_image,
            R.drawable.third_background_image
        )
    }

      fun onCreate(savedInstanceState: Bundle) {
           super.onCreate(savedInstanceState)
            .......
            .......
            IntroAdapter().apply {   
                submitList(centeredImageResources)
            }.also { introScreenViewPager.adapter = it }   // 2   
      }
}
  • Image resources for centered ImageView.
  • Setting-up the InfoAdapter on introScreenViewPager.

Step4: Setting-up ViewPager on WormDotIndicator

We can add the dot indicator on ViewPager with just a single code.

wormIndicator.setViewPager2(introScreenViewPager)

Step5: Registering OnPageChangeCallback on ViewPager2 instance

This most important thing in this tutorial example is to register a callback and when the user interacts with the ViewPager (page position changes) shows a different image inside the ImagView.

class IntroScreenActivity: AppCompatActivity() {

     private val viewPagerOnChangeCallback= object : ViewPager2.OnPageChangeCallback() {
          override fun onPageSelected(poisition: Int) {
              splashScreenCenterImageView.setImageResource(centeredImageResources[position])
          }
     }

     override fun onCreate(savedInstanceState: Bundle) {
          super.onCreate(savedInstanceState)
          .......
          .......
          introScreenViewPager.registerOnPageChangeCallback(viewPagerOnChangeCallback)     
     }
}

Last Step: Setting-up ViewPager Adapter

The InfoAdapter is the core piece of this article. Usually, the ViewPager adapter contains information about the data which displays but in our case it must be an empty adapter. Because the ViewPager is not showing any info it’s just helping us to swipe on the screen.

Now you must be thinking that! then WHY the hack I’m adding adapter on ViewPager. Well, that’s because of the ViewPager2 and WormDotsIndicator will not work properly if I skipped that.

class IntroAdapter : ListAdapter<Int, IntroAdapter.Companion.EmptyViewHolder>(
    DIFF_CALLBACK
) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
        EmptyViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.empty_match_parent_layout,
                parent,
                false
            )
        )

    override fun onBindViewHolder(holder: EmptyViewHolder, position: Int) {}

    companion object {
        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Int>() {
            override fun areItemsTheSame(oldItem: Int, newItem: Int) = oldItem == newItem

            override fun areContentsTheSame(oldItem: Int, newItem: Int) = oldItem == newItem
        }

        class EmptyViewHolder(view: View) : RecyclerView.ViewHolder(view)
    }
}

And that’s it! we’re done! Run the app see the result.


So now if you need a ViewPager2 with static content and don’t want the headache of adding fragments, you have the above solution. The complete code of the android ViewPager2 example is on GitHub.

Thanks for being here and keep reading…

Write A Comment