Uso de ViewPager2 en Android
android-viewpager android-viewpager2 (3)
Llegué a conocer sobre ViewPager2 y ViewPager2 de implementarlo, pero no encontré ningún ejemplo adecuado.
¿Alguien puede decirme cómo puedo usarlo?
Estoy buscando una pista, no un ejemplo.
Uso de ViewPager2 en Android
Como se mencionó en el ViewPager2
Cambios de API
FragmentStateAdapter reemplaza a FragmentStatePagerAdapter
RecyclerView.Adapter reemplaza a PagerAdapter
registerOnPageChangeCallback reemplaza addPageChangeListener
En Palabras sencillas, hacen que el adaptador de Visor de páginas funcione como el Adaptador de vista de reciclaje.
Nota: - No necesitamos usar el fragmento en View Pager 2. Depende completamente del diseño inflado de RecyclerView.Adapter.
Aquí está la muestra gitHub repo Link
Ejemplo:-
MainActivity.class
public class MainActivity extends AppCompatActivity {
private ViewPager2 mPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("View Pager 2");
mPager = findViewById(R.id.pager);
mPager.setAdapter(new MyViewPagerAdapter(this));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (R.id.change == item.getItemId()) {
mPager.setOrientation(mPager.getOrientation() != ViewPager2.ORIENTATION_VERTICAL ? ViewPager2.ORIENTATION_VERTICAL : ViewPager2.ORIENTATION_HORIZONTAL);
}
return super.onOptionsItemSelected(item);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
MyViewPagerAdapter.class
public class MyViewPagerAdapter extends RecyclerView.Adapter<MyHolder> {
private Context context;
public MyViewPagerAdapter(Context context) {
this.context=context;
}
@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyHolder(LayoutInflater.from(context).inflate(R.layout.cell_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position) {
holder.mText.setText("Page "+(position+1));
}
@Override
public int getItemCount() {
return 10;
}
}
cell_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Page 1"
android:textSize="20sp" />
</android.support.constraint.ConstraintLayout>
MyHolder.class
class MyHolder extends RecyclerView.ViewHolder {
public TextView mText;
public MyHolder(@NonNull View itemView) {
super(itemView);
mText = itemView.findViewById(R.id.text);
}
}
salida:
Desde docs
Nuevas características
- Soporte de diseño de derecha a izquierda (RTL)
- Soporte de orientacion vertical
- notifyDataSetChanged completamente funcional
Cambios de API
-
FragmentStateAdapter
reemplaza aFragmentStatePagerAdapter
-
RecyclerView.Adapter
reemplaza aPagerAdapter
-
registerOnPageChangeCallback
reemplazaaddPageChangeListener
CÓDIGO DE MUESTRA
agrega las últimas
dependencies
paraViewPager2
implementation ''androidx.viewpager2:viewpager2:1.0.0-alpha01''
diseño
<?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>
actividad
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);
}
}
}
Nuevas características
ahora necesitamos usar
ViewPager2.OnPageChangeCallback()
para obtener el evento Swipe deViewPager2
CÓDIGO DE MUESTRA
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);
}
});
podemos establecer la orientación utilizando
myViewPager2.setOrientation()
CÓDIGO DE MUESTRA
Para uso de
HORIZONTAL Orientation
myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
Para uso de
VERTICAL Orientation
myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
Podemos usar
notifyDataSetChanged
igual que usamos enRecyclerView.Adapter
CÓDIGO DE MUESTRA para agregar nuevo artículo
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arrayList.add("New ITEM ADDED");
MyAdapter.notifyDataSetChanged();
}
});
CÓDIGO DE MUESTRA para eliminar nuevo artículo
btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arrayList.remove(3);
MyAdapter.notifyItemRemoved(3);
}
});
ACTUALIZAR
Intenta esto si quieres usar
Fragment
con
ViewPager2
Primero cree una clase
ViewPagerFragmentAdapter
que extiendaFragmentStateAdapter
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();
}
}
Ahora usa así en tu actividad.
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);
}
}
para mas informacion revisa esto
ACTUALIZACIÓN 2
Nuevas características
-
Posibilidad de deshabilitar la entrada del usuario (
setUserInputEnabled
,isUserInputEnabled
)
Cambios de API
-
ViewPager2
class final
Corrección de errores
-
FragmentStateAdapter
correcciones de estabilidad
CÓDIGO DE MUESTRA para deshabilitar el deslizamiento en viewpager2
myViewPager2.setUserInputEnabled(false);// SAMPLE CODE to disable swiping in viewpager2
myViewPager2.setUserInputEnabled(true);//SAMPLE CODE to enable swiping in viewpager2
ACTUALIZACIÓN 3
Nuevas características
- Posibilidad de desplazarse mediante programación ViewPager2: fakeDragBy (offsetPx) .
Cambios de API
-
FragmentStateAdapter
ahora requiere un objetoLifecycle
. Se agregaron dos constructores de utilidades para obtenerlo del hostFragmentActivity
o del host Fragment
CÓDIGO DE MUESTRA
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();
}
}
Código de actividad principal
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);
}
}
ACTUALIZACIÓN 4
Version 1.0.0-alpha05
Nuevas características
-
ItemDecorator
introdujo un comportamiento consistente conRecyclerView
. -
MarginPageTransformer
introdujoMarginPageTransformer
para proporcionar la capacidad de crear espacio entre páginas (fuera de la inserción de la página). -
CompositePageTransformer
introdujoCompositePageTransformer
para proporcionar la capacidad de combinar variosPageTransformers
Cambios de API
-
FragmentStateAdapter#getItem
métodoFragmentStateAdapter#getItem
renombrado aFragmentStateAdapter#createFragment
: el nombre del método anterior ha demostrado ser una fuente de errores en el pasado. -
OFFSCREEN_PAGE_LIMIT_DEFAULT
valor deOFFSCREEN_PAGE_LIMIT_DEFAULT
cambió de 0 a -1. No es necesario cambiar el código del cliente si se utiliza elOFFSCREEN_PAGE_LIMIT_DEFAULTconstant
.
CÓDIGO DE MUESTRA
Codigo de actividad
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;
}
}
En realidad, ahora hay un repositorio de muestras oficiales para ViewPager2 (enlazado a continuación)
Repo contiene las siguientes muestras (Cotización del léame de repositorio a continuación)
Muestras
- ViewPager2 con vistas: muestra cómo configurar un ViewPager2 con vistas como páginas
- ViewPager2 con fragmentos: muestra cómo configurar un ViewPager2 con fragmentos como páginas
- ViewPager2 con una colección mutable (vistas): demuestra el uso de ViewPager2 con vistas como páginas y mutaciones en un adaptador de página
- ViewPager2 con una colección mutable (fragmentos): muestra el uso de ViewPager2 con fragmentos como páginas y mutaciones en un adaptador de página
- ViewPager2 con un TabLayout (Vistas): muestra cómo configurar un ViewPager2 con vistas como páginas y vincularlo a un TabLayout
Algunos otros recursos útiles:
- Docs: https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2
-
Entrenamiento: https://developer.android.com/training/animation/screen-slide-2
-
Notas de la versión: ViewPager2
-
Artículo mediano por un GDE: Explorando el ViewPager2