Sliding Images with ViewPager Example | PagerAdapter

ViewPager Example
Spread knowledge

In this ViewPager example we will create an application which displays a sequence of  Images in ViewPager with help of PagerAdapter. We will also implement a CirculerIndicator to indicate the current view.

ViewPager is a layout manager which allows user to flip left and right through pages of data. Such interaction enriches user experience and is useful in displaying sequence of pages seamlessly. This is the reason why many modern apps use ViewPager extensively.

ViewPager is popularly used with fragments. Over there each fragment acts as a page and user can view multiple fragments by just swiping left and right on the screen. With fragments developers have a much wider range of possibility to show in a single page as each fragment has its own layout file and lifecycle. But there might be lot of cases where we don’t need such complex pages in our ViewPager. To visualize you can think of  a  ecommerce app which wants to display sliding banners of daily offers on its home screen as shown below. In these scenarios we can use simple Views instead of Fragments

 

Step 1 Adding Dependencies

For this ViewPager example to work add the following in your build.gradle

implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'me.relex:circleindicator:1.2.2@aar'

Step 2 Design layout for your activity

Add ViewPager and CircleIndicator to your layout file as shown below

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.irshadkumail.pagerexample.MainActivity">
  <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="220dp" />
  <me.relex.circleindicator.CircleIndicator
        android:id="@+id/circle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/view_pager"
        android:layout_centerHorizontal="true"
        android:padding="16dp" />
</RelativeLayout>

 

Step 3 Layout File for ViewPager Item

Create a layout file pager_item.xml. This layout file will be used for each page of your ViewPager. Since we are just displaying sequence of different images we can use the same layout for all our pages.

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="220dp"></ImageView>

</ImageView>

 

Step 4 Creating PagerAdapter

Whether the pages are Fragment or Views, Adapter is what creates and provides pages to your ViewPager. For fragment we usually implement FragmentStatePagerAdapter whereas for Views we will be implementing PagerAdapter.

When implementing PagerAdapter it is mandatory to override these methods

  • instantiateItem() :  This is to create a page at a given position in your ViewPager.  It returns a Object variable representing the page.
  • destroyItem() :   This is to destroy a page at a given position in your ViewPager. One of the parameter passed is the Object variable returned by the instantiateItem() method.
  • getCount() : Returns the total count of pages/views in your ViewPager.
  • isViewFromObject() : This method is required by PagerAdapter to function properly. It determines whether the page view is associated with the specific object returned by instantiateItem() 

You must have noticed that instantiateItem, which creates a page view, returns a Object variable instead of a View. This is because ViewPager associates each page with a key object rather than a View. This key is used to track and uniquely identify a given page independent of its position in the adapter. For the same reason we need isViewFromObject() to determine which view belongs to which key.

In this example we will use View only as key object, thereby directly returning the View in instantiateItem() after adding it to the parent ViewGroup. Similarly in destroyItem() we will remove the View passed as a Param from the parent ViewGroup. isViewFromObject will simply return view == object which will always be true.

public class MyPager extends PagerAdapter {

    private Context context;

    public MyPager(Context context) {

        this.context = context;
    }

    /*
    This callback is responsible for creating a page. We inflate the layout and set the drawable
    to the ImageView based on the position. In the end we add the inflated layout to the parent
    container .This method returns an object key to identify the page view, but in this example page view
    itself acts as the object key
    */

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

        View view = LayoutInflater.from(context).inflate(R.layout.linear_layout, null);
        ImageView imageView = view.findViewById(R.id.image);
        imageView.setImageDrawable(context.getResources().getDrawable(getImageAt(position)));
        container.addView(view);
        return view;
    }

    /*
    This callback is responsible for destroying a page. Since we are using view only as the
    object key we just directly remove the view from parent container
    */
    @Override
    public void destroyItem(ViewGroup container, int position, Object view) {

        container.removeView((View) view);

    }

    /*
    Returns the count of the total pages
    */
    @Override
    public int getCount() {
        return 4;
    }

    /*
    Used to determine whether the page view is associated with object key returned by instantiateItem.
    Since here view only is the key we return view==object
    */

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

    private int getImageAt(int position) {
        switch (position) {
            case 0:
                return R.drawable.india_taj_mahal;
            case 1:
                return R.drawable.colosseum;
            case 2:
                return R.drawable.eiffel_tower;
            case 3:
                return R.drawable.statue_of_liberty;
            default:
                return R.drawable.india_taj_mahal;
        }

    }

}

 

Step 5 

Once we have implemented PagerAdapter we just need to instantiate it in our MainActivity and associate it with the ViewPager. For the Circularindicator we just need to associate it with the ViewPager and it takes care of the rest on its own.

public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;

    private CircleIndicator circleIndicator;

    private MyPager myPager;

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

        myPager = new MyPager(this);
        viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(myPager);
        circleIndicator = findViewById(R.id.circle);
        circleIndicator.setViewPager(viewPager);

    }
}

 

 

viewpager example

This completes our ViewPager Example . Above GIF gives a visual representation of how our app will look after this implementation. These sliding images definitely adds a visual appeal to your app.

We have a amazing collection of Android Examples which could help you become a better developer. Make sure you read them


Spread knowledge

Leave a Reply

Your email address will not be published. Required fields are marked *