Android Infinite Auto Image Slider using View Pager 2 | Android Studio | Java

Golap Gunjan Barman
The Startup
Published in
5 min readFeb 13, 2021

In this tutorial, we will create an infinite auto image slider using view pager 2. For infinite sliding, we will implement a new technique that saves memory for loading images.

Add the dependency

Before implementation, it adds the dependency for the view pager 2 and rounded image view.

In build.gradle

dependencies {
//viewpager 2
implementation “androidx.viewpager2:viewpager2:1.0.0”

//rounded imageview
implementation ‘com.makeramen:roundedimageview:2.3.0’
}

Add the viewpager2

Now in the main XML file, add the viewpager2 for displaying the images.

<?xml version=”1.0" encoding=”utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=”.MainActivity”
android:background=”@color/white”>
<androidx.viewpager2.widget.ViewPager2
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:paddingStart=”80dp”
android:paddingEnd=”80dp”
android:id=”@+id/viewPagerImageSlider”/>
</androidx.constraintlayout.widget.ConstraintLayout>

Design the item

Now create a new layout file (/res/layout/slide_item_container.xml) for the slider item, where we add the rounded image view.

<?xml version=”1.0" encoding=”utf-8"?>
<com.makeramen.roundedimageview.RoundedImageView xmlns:android=”http://schemas.android.com/apk/res/android"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
xmlns:app=”http://schemas.android.com/apk/res-auto"
android:id=”@+id/imageSlide”
app:riv_corner_radius=”12dp”
android:adjustViewBounds=”true”>
</com.makeramen.roundedimageview.RoundedImageView>

Class for images

Now create a new java (/package/SliderItems.java) file for getting the images

package com.codewithgolap.imageslider;
public class SliderItems {
//set to String, if you want to add image url from internet
private int image
;
SliderItems(int image) {
this.image = image
;
}
public int getImage() {
return image
;
}
}

Create an Adapter

Now create an adapter (/package/SliderAdapter.java) for inflate our item layout and binding the view.

public class SliderAdapter extends RecyclerView.Adapter<SliderAdapter.SliderViewHolder> {
private List<SliderItems> sliderItems
;
private ViewPager2 viewPager2;
SliderAdapter(List<SliderItems> sliderItems, ViewPager2 viewPager2) {
this.sliderItems = sliderItems
;
this.viewPager2 = viewPager2;
}
@NonNull
@Override
public SliderViewHolder onCreateViewHolder(@NonNull ViewGroup parent
, int viewType) {
return new SliderViewHolder(
LayoutInflater.
from(parent.getContext()).inflate(
R.layout.
slide_item_container, parent, false
) )
;
}
@Override
public void onBindViewHolder(@NonNull SliderViewHolder holder
, int position) {
holder.setImage(sliderItems.get(position))
;
if (position == sliderItems.size()- 2){
viewPager2.post(runnable)
;
}
}
@Override
public int getItemCount() {
return sliderItems.size()
;
}
class SliderViewHolder extends RecyclerView.ViewHolder {
private RoundedImageView imageView
;
SliderViewHolder(@NonNull View itemView) {
super(itemView)
;
imageView = itemView.findViewById(R.id.imageSlide);
}
void setImage(SliderItems sliderItems){
//use glide or picasso in case you get image from internet
imageView.setImageResource(sliderItems.getImage())
;
}
}

}

Add the functionality

Now in the main java file, attach the images, and set our adapter with viewpager.

public class MainActivity extends AppCompatActivity {

private ViewPager2 viewPager2
;

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

viewPager2 = findViewById(R.id.viewPagerImageSlider);

List<SliderItems> sliderItems = new ArrayList<>();
sliderItems.add(new SliderItems(R.drawable.image1));
sliderItems.add(new SliderItems(R.drawable.image2));
sliderItems.add(new SliderItems(R.drawable.image3));
sliderItems.add(new SliderItems(R.drawable.image4));
sliderItems.add(new SliderItems(R.drawable.image5));

viewPager2.setAdapter(new SliderAdapter(sliderItems,viewPager2));

}
}

Add functionality for infinite auto slider

  • For that add, a runnable method in the viewpager also adds some changes in the main java file.

public class MainActivity extends AppCompatActivity {

private ViewPager2 viewPager2
;
private Handler sliderHandler = new Handler();

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

viewPager2 = findViewById(R.id.viewPagerImageSlider);

List<SliderItems> sliderItems = new ArrayList<>();
sliderItems.add(new SliderItems(R.drawable.image1));
sliderItems.add(new SliderItems(R.drawable.image2));
sliderItems.add(new SliderItems(R.drawable.image3));
sliderItems.add(new SliderItems(R.drawable.image4));
sliderItems.add(new SliderItems(R.drawable.image5));

viewPager2.setAdapter(new SliderAdapter(sliderItems,viewPager2));

viewPager2.setClipToPadding(false);
viewPager2.setClipChildren(false);
viewPager2.setOffscreenPageLimit(3);
viewPager2.getChildAt(0).setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);

CompositePageTransformer compositePageTransformer = new CompositePageTransformer();
compositePageTransformer.addTransformer(new MarginPageTransformer(40));
compositePageTransformer.addTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page
, float position) {
float r =
1 — Math.abs(position);
page.setScaleY(0.85f + r * 0.15f);
}
})
;

viewPager2.setPageTransformer(compositePageTransformer);

viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position)
;
sliderHandler.removeCallbacks(sliderRunnable);
sliderHandler.postDelayed(sliderRunnable, 2000); // slide duration 2 seconds
}
})
;
}

private Runnable sliderRunnable = new Runnable() {
@Override
public void run() {
viewPager2.setCurrentItem(viewPager2.getCurrentItem() +
1);
}
}
;
}

  • same way add a runnable method in the adapter class.

private Runnable runnable = new Runnable() {
@Override
public void run() {
sliderItems.addAll(sliderItems)
;
notifyDataSetChanged();
}
}
;

Save memory

Now for saving the memory, that means when we minimize the app it remains the same where we pause the app, again when we resume the app the slider will continue with the auto slider.

@Override
protected void onPause() {
super.onPause()
;
sliderHandler.removeCallbacks(sliderRunnable);
}

@Override
protected void onResume() {
super.onResume()
;
sliderHandler.postDelayed(sliderRunnable, 2000);
}

Output

  • only infinite auto image slider
  • save memory using onPause() and onResume() methods

Source code:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout 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=”.MainActivity”
android:background=”@color/white”>

<androidx.viewpager2.widget.ViewPager2
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:paddingStart=”80dp”
android:paddingEnd=”80dp”
android:id=”@+id/viewPagerImageSlider”/>

</androidx.constraintlayout.widget.ConstraintLayout>

slide_item_container.xml

<?xml version=”1.0" encoding=”utf-8"?>
<com.makeramen.roundedimageview.RoundedImageView xmlns:android=”http://schemas.android.com/apk/res/android"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
xmlns:app=”http://schemas.android.com/apk/res-auto"
android:id=”@+id/imageSlide”
app:riv_corner_radius=”12dp”
android:adjustViewBounds=”true”>

</com.makeramen.roundedimageview.RoundedImageView>

SliderItems.java

package com.codewithgolap.imageslider;

public class SliderItems {

//set to String, if you want to add image url from internet
private int image
;

SliderItems(int image) {
this.image = image
;
}

public int getImage() {
return image
;
}
}

SliderAdapter.java

package com.codewithgolap.imageslider;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import com.makeramen.roundedimageview.RoundedImageView;

import java.util.List;

public class SliderAdapter extends RecyclerView.Adapter<SliderAdapter.SliderViewHolder> {

private List<SliderItems> sliderItems
;
private ViewPager2 viewPager2;

SliderAdapter(List<SliderItems> sliderItems, ViewPager2 viewPager2) {
this.sliderItems = sliderItems
;
this.viewPager2 = viewPager2;
}

@NonNull
@Override
public SliderViewHolder onCreateViewHolder(@NonNull ViewGroup parent
, int viewType) {
return new SliderViewHolder(
LayoutInflater.
from(parent.getContext()).inflate(
R.layout.
slide_item_container, parent, false
)
)
;
}

@Override
public void onBindViewHolder(@NonNull SliderViewHolder holder
, int position) {
holder.setImage(sliderItems.get(position))
;
if (position == sliderItems.size()- 2){
viewPager2.post(runnable)
;
}
}

@Override
public int getItemCount() {
return sliderItems.size()
;
}

class SliderViewHolder extends RecyclerView.ViewHolder {
private RoundedImageView imageView
;

SliderViewHolder(@NonNull View itemView) {
super(itemView)
;
imageView = itemView.findViewById(R.id.imageSlide);
}

void setImage(SliderItems sliderItems){

//use glide or picasso in case you get image from internet
imageView.setImageResource(sliderItems.getImage())
;
}
}

private Runnable runnable = new Runnable() {
@Override
public void run() {
sliderItems.addAll(sliderItems)
;
notifyDataSetChanged();
}
}
;

}

MainActivity.java

package com.codewithgolap.imageslider;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.CompositePageTransformer;
import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

private ViewPager2 viewPager2
;
private Handler sliderHandler = new Handler();

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

viewPager2 = findViewById(R.id.viewPagerImageSlider);

List<SliderItems> sliderItems = new ArrayList<>();
sliderItems.add(new SliderItems(R.drawable.image1));
sliderItems.add(new SliderItems(R.drawable.image2));
sliderItems.add(new SliderItems(R.drawable.image3));
sliderItems.add(new SliderItems(R.drawable.image4));
sliderItems.add(new SliderItems(R.drawable.image5));

viewPager2.setAdapter(new SliderAdapter(sliderItems,viewPager2));

viewPager2.setClipToPadding(false);
viewPager2.setClipChildren(false);
viewPager2.setOffscreenPageLimit(3);
viewPager2.getChildAt(0).setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);

CompositePageTransformer compositePageTransformer = new CompositePageTransformer();
compositePageTransformer.addTransformer(new MarginPageTransformer(40));
compositePageTransformer.addTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page
, float position) {
float r =
1 — Math.abs(position);
page.setScaleY(0.85f + r * 0.15f);
}
})
;

viewPager2.setPageTransformer(compositePageTransformer);

viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position)
;
sliderHandler.removeCallbacks(sliderRunnable);
sliderHandler.postDelayed(sliderRunnable, 2000); // slide duration 2 seconds
}
})
;
}

private Runnable sliderRunnable = new Runnable() {
@Override
public void run() {
viewPager2.setCurrentItem(viewPager2.getCurrentItem() +
1);
}
}
;

@Override
protected void onPause() {
super.onPause()
;
sliderHandler.removeCallbacks(sliderRunnable);
}

@Override
protected void onResume() {
super.onResume()
;
sliderHandler.postDelayed(sliderRunnable, 2000);
}
}

YouTube: https://youtu.be/gOG5iTMj31U

For more visit my website/blog: www.gbandroidblogs.com

--

--

Golap Gunjan Barman
The Startup

Hi everyone, myself Golap an Android app developer with UI/UX designer.