Android Viewpager Implementation

Proper implementation of ViewPager2 in Android

UPDATE 7

Check : Migrate from ViewPager to ViewPager2

Check : Create swipe views with tabs using ViewPager2

UPDATE 6

Check out my answer if you want to implement Carousel using View Pager2

UPDATE 5

How to use TabLayout with ViewPager2

SAMPLE CODE

Use below dependencies

implementation 'com.google.android.material:material:1.1.0-alpha08'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'

SAMPLE CODE

XMl layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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">

<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.appbar.AppBarLayout>

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
app:layout_anchor="@id/tabs"
app:layout_anchorGravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import com.google.android.material.tabs.TabLayoutMediator

import com.google.android.material.tabs.TabLayout

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// setSupportActionBar(toolbar)
viewpager.adapter = AppViewPagerAdapter(supportFragmentManager, lifecycle)

TabLayoutMediator(tabs, viewpager, object : TabLayoutMediator.OnConfigureTabCallback {
override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
// Styling each tab here
tab.text = "Tab $position"
}
}).attach()

}
}

OUTPUT

TabLayout with ViewPager2

From Docs

ViewPager2

New features

  • Right-to-left (RTL) layout support
  • Vertical orientation support
  • notifyDataSetChanged fully functional

API changes

  • FragmentStateAdapter replaces FragmentStatePagerAdapter
  • RecyclerView.Adapter replaces PagerAdapter
  • registerOnPageChangeCallback replaces addPageChangeListener

SAMPLE CODE

add the latest dependencies for ViewPager2

implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha01'

layout

<?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=".MainActivity">

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>

activity

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import java.util.ArrayList;

public class MyActivity extends AppCompatActivity {

ViewPager2 myViewPager2;
MyAdapter MyAdapter;
private ArrayList<String> arrayList = new ArrayList<>();

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

myViewPager2 = findViewById(R.id.view_pager);

arrayList.add("Item 1");
arrayList.add("Item 2");
arrayList.add("Item 3");
arrayList.add("Item 4");
arrayList.add("Item 5");

MyAdapter = new MyAdapter(this, arrayList);

myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

myViewPager2.setAdapter(MyAdapter);
}
}

MyAdapter

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

private Context context;
private ArrayList<String> arrayList = new ArrayList<>();

public MyAdapter(Context context, ArrayList<String> arrayList) {
this.context = context;
this.arrayList = arrayList;
}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tvName.setText(arrayList.get(position));
}

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

public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvName;

public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvName);
}
}
}

New features

now we need to use ViewPager2.OnPageChangeCallback() to get Swipe event of ViewPager2

SAMPLE CODE

    myViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}

@Override
public void onPageSelected(int position) {
super.onPageSelected(position);

Log.e("Selected_Page", String.valueOf(position));
}

@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});

we can set Orientation using myViewPager2.setOrientation()

SAMPLE CODE

For HORIZONTAL Orientation use

myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);

For VERTICAL Orientation use

myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

We can use notifyDataSetChanged same as we are using in RecyclerView.Adapter

SAMPLE CODE to add new item

    btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arrayList.add("New ITEM ADDED");
MyAdapter.notifyDataSetChanged();
}
});

SAMPLE CODE to remove new item

    btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arrayList.remove(3);
MyAdapter.notifyItemRemoved(3);
}
});

UPDATE

Try this if you want to use Fragment with ViewPager2

First create a ViewPagerFragmentAdapter class which extends FragmentStateAdapter

import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

private ArrayList<Fragment> arrayList = new ArrayList<>();

public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager) {
super(fragmentManager);
}

@NonNull
@Override
public Fragment getItem(int position) {
return arrayList.get(position);
}

public void addFragment(Fragment fragment) {
arrayList.add(fragment);
}

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

Now use like this in your activity

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;

public class MainActivity extends AppCompatActivity {

ViewPager2 myViewPager2;
ViewPagerFragmentAdapter myAdapter;

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

myViewPager2 = findViewById(R.id.view_pager);

myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager());

// add Fragments in your ViewPagerFragmentAdapter class
myAdapter.addFragment(new FragmentOne());
myAdapter.addFragment(new Fragmenttwo());
myAdapter.addFragment(new FragmentThree());

// set Orientation in your ViewPager2
myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

myViewPager2.setAdapter(myAdapter);

}

}

for more information check this

  • ViewPager2
  • ViewPager2 under the Hood
  • Hands on With ViewPager2

UPDATE 2

Version 1.0.0-alpha02

New features

  • Ability to disable user input (setUserInputEnabled, isUserInputEnabled)

API changes

  • ViewPager2 class final

Bug fixes

  • FragmentStateAdapter stability fixes

SAMPLE CODE to disable swiping in viewpager2

myViewPager2.setUserInputEnabled(false);// SAMPLE CODE to disable swiping in viewpager2

myViewPager2.setUserInputEnabled(true);//SAMPLE CODE to enable swiping in viewpager2

UPDATE 3

Version 1.0.0-alpha03

New features

  • Ability to programmatically scroll ViewPager2: fakeDragBy(offsetPx).

API changes

  • FragmentStateAdapter now requires a Lifecycle object. Two utility constructors added to obtain it from the host FragmentActivity or the host Fragment

SAMPLE CODE

ViewPagerFragmentAdapter

import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

private ArrayList<Fragment> arrayList = new ArrayList<>();

public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}

@NonNull
@Override
public Fragment getItem(int position) {
return arrayList.get(position);
}

public void addFragment(Fragment fragment) {
arrayList.add(fragment);
}

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

MainActivity code

import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;

public class MainActivity extends AppCompatActivity {

ViewPager2 myViewPager2;
ViewPagerFragmentAdapter myAdapter;

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

myViewPager2=findViewById(R.id.view_pager);
myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle());

// add Fragments in your ViewPagerFragmentAdapter class
myAdapter.addFragment(new FragmentOne());
myAdapter.addFragment(new Fragmenttwo());
myAdapter.addFragment(new FragmentThree());

myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

myViewPager2.setAdapter(myAdapter);
}
}

UPDATE 4

Version 1.0.0-alpha05
New features

  • ItemDecorator introduced with a behaviour consistent with RecyclerView.
  • MarginPageTransformer introduced to provide an ability to create space between pages (outside of page inset).
  • CompositePageTransformer introduced to provide an ability to combine multiple PageTransformers

API changes

  • FragmentStateAdapter#getItem method renamed to FragmentStateAdapter#createFragment - previous method name has proven to be a source of bugs in the past.
  • OFFSCREEN_PAGE_LIMIT_DEFAULT value changed from 0 to -1. No need for a client code change if the OFFSCREEN_PAGE_LIMIT_DEFAULTconstant used.

SAMPLE CODE

Activity code

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;

public class MainActivity extends AppCompatActivity {

ViewPager2 myViewPager2;
ViewPagerFragmentAdapter myAdapter;
private ArrayList<Fragment> arrayList = new ArrayList<>();

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

myViewPager2 = findViewById(R.id.myViewPager2);

// add Fragments in your ViewPagerFragmentAdapter class
arrayList.add(new FragmentOne());
arrayList.add(new Fragmenttwo());
arrayList.add(new FragmentThree());

myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle());
// set Orientation in your ViewPager2
myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);

myViewPager2.setAdapter(myAdapter);

myViewPager2.setPageTransformer(new MarginPageTransformer(1500));

}
}

ViewPagerFragmentAdapter

import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

private ArrayList<Fragment> arrayList = new ArrayList<>();

public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}

@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new Fragmenttwo();
case 2:
return new FragmentThree();

}
return null;
}

@Override
public int getItemCount() {
return 3;
}
}

implementation of viewPager2

yes that link helped . I changed these lines of codes:

 tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){

@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
}

@Override
public void onTabReselected(TabLayout.Tab tab) {

}
});

viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
tabLayout.selectTab(tabLayout.getTabAt(position));
}
});

How to implement ViewPager with fragments in AndroidX

Your ViewPagerAdapter class has a constructor that takes 2 parameters.

When you try to create a new ViewPagerAdapter, you only use 1 parameter.

Which is exactly what the error message is telling you.

Look at the documentation for the FragmentPagerAdapter class and see what the 2nd parameter should be.

How to implement a ViewPager with different Fragments / Layouts

As this is a very frequently asked question, I wanted to take the time and effort to explain the ViewPager with multiple Fragments and Layouts in detail. Here you go.

ViewPager with multiple Fragments and Layout files - How To

The following is a complete example of how to implement a ViewPager
with different fragment Types and different layout files.

In this case, I have 3 Fragment classes, and a different layout file for each class. In order to keep things simple, the fragment-layouts only differ in their background color. Of course, any layout-file can be used for the Fragments.

FirstFragment.java has a orange background layout, SecondFragment.java has a green background layout and ThirdFragment.java has a red background layout. Furthermore, each Fragment displays a different text, depending on which class it is from and which instance it is.

Also be aware that I am using the support-library's Fragment:
android.support.v4.app.Fragment

MainActivity.java (Initializes the Viewpager and has the adapter for it as an inner class). Again have a look at the imports. I am using the android.support.v4 package.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {

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

ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}

private class MyPagerAdapter extends FragmentPagerAdapter {

public MyPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int pos) {
switch(pos) {

case 0: return FirstFragment.newInstance("FirstFragment, Instance 1");
case 1: return SecondFragment.newInstance("SecondFragment, Instance 1");
case 2: return ThirdFragment.newInstance("ThirdFragment, Instance 1");
case 3: return ThirdFragment.newInstance("ThirdFragment, Instance 2");
case 4: return ThirdFragment.newInstance("ThirdFragment, Instance 3");
default: return ThirdFragment.newInstance("ThirdFragment, Default");
}
}

@Override
public int getCount() {
return 5;
}
}
}

activity_main.xml (The MainActivitys .xml file) - a simple layout file, only containing the ViewPager that fills the whole screen.

<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

The Fragment classes, FirstFragment.java
import android.support.v4.app.Fragment;

public class FirstFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_frag, container, false);

TextView tv = (TextView) v.findViewById(R.id.tvFragFirst);
tv.setText(getArguments().getString("msg"));

return v;
}

public static FirstFragment newInstance(String text) {

FirstFragment f = new FirstFragment();
Bundle b = new Bundle();
b.putString("msg", text);

f.setArguments(b);

return f;
}
}

first_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_orange_dark" >

<TextView
android:id="@+id/tvFragFirst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="26dp"
android:text="TextView" />
</RelativeLayout>

SecondFragment.java

public class SecondFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.second_frag, container, false);

TextView tv = (TextView) v.findViewById(R.id.tvFragSecond);
tv.setText(getArguments().getString("msg"));

return v;
}

public static SecondFragment newInstance(String text) {

SecondFragment f = new SecondFragment();
Bundle b = new Bundle();
b.putString("msg", text);

f.setArguments(b);

return f;
}
}

second_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_green_dark" >

<TextView
android:id="@+id/tvFragSecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="26dp"
android:text="TextView" />

</RelativeLayout>

ThirdFragment.java

public class ThirdFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.third_frag, container, false);

TextView tv = (TextView) v.findViewById(R.id.tvFragThird);
tv.setText(getArguments().getString("msg"));

return v;
}

public static ThirdFragment newInstance(String text) {

ThirdFragment f = new ThirdFragment();
Bundle b = new Bundle();
b.putString("msg", text);

f.setArguments(b);

return f;
}
}

third_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_red_light" >

<TextView
android:id="@+id/tvFragThird"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="26dp"
android:text="TextView" />

</RelativeLayout>

The end result is the following:

The Viewpager holds 5 Fragments, Fragments 1 is of type FirstFragment, and displays the first_frag.xml layout, Fragment 2 is of type SecondFragment and displays the second_frag.xml, and Fragment 3-5 are of type ThirdFragment and all display the third_frag.xml.

Sample Image

Above you can see the 5 Fragments between which can be switched via swipe to the left or right. Only one Fragment can be displayed at the same time of course.

Last but not least:

I would recommend that you use an empty constructor in each of your
Fragment classes.

Instead of handing over potential parameters via constructor, use the newInstance(...) method and the Bundle for handing over parameters.

This way if detached and re-attached the object state can be stored through the arguments. Much like Bundles attached to Intents.

How to use Android ViewPager?

Try this site - Page swiping using ViewPager

This will help you to implement view pager step by step.

ViewPager Example

android viewPager implementation

This helped me a lot: http://geekyouup.blogspot.com/2011/07/viewpager-example-from-paug.html

Theres a link to some googlecode you can download and paw through too.

Viewpagers work like list views. To use it with two layouts you're going to have to expand the layouts in a LayoutInflater and add as a view to each page.

ViewPager - vertical and horizontal implementation at the same time

I just built a DoubleFragmentViewpager library that should do what you want.

I just tried it myself so maybe it's not that robust but you could give it a try.

If you can afford not using fragments, I also recommand you the juliome10's DoubleViewPager.



Related Topics



Leave a reply



Submit