Cómo conservar el estado de ViewPager dentro de un RecyclerView?
Mi RecyclerView contiene muchos ViewPagers. El número de páginas dentro de cada ViewPager es constante (2). Yo uso PagerAdapter.
Cuando recorro mi RecyclerView, los ViewPagers pierden su estado y vuelven a la primera página. Quiero saber cómo conservar la última página seleccionada para cada ViewPager.
- Android ViewPager con RecyclerView funciona incorrectamente dentro de BottomSheet
- Cómo acceder a las vistas desde el buscapersonas
- ¿Cuál es la distancia mínima predeterminada para desplazarse correctamente en View Pager?
- Visualización de varias páginas en ViewPager, posición incorrecta
- ¿Cuándo debería getItemPosition considerar cambios en la posición de un ítem?
Por ejemplo: 1) Desplácese a la página 2 en mi 1 ViewPager 2) Desplácese el RecyclerView a la parte inferior y mi 1 ViewPager sale de la pantalla. 3) Me desplazo a la tapa del ViewPager y así que mi 1 ViewPager carga otra vez. 4) Mi ViewPager primero se establece en la 1 ª página en lugar de la página 2, que se desplazó por último a.
Hay 'n' número de ViewPagers dentro de RecyclerView y quiero conservar todos sus estados independientemente de la recarga debido a RecyclerView.
¿Cómo resolver esta lógica?
- Establecer la altura de Viewpager dentro de Scrollview en android
- Cómo arrastrar un botón de acción flotante sobre un paginador de vista
- Reemplazar ViewPager con Fragmento - y luego volver a navegar
- Recuperar un fragmento de un ViewPager
- ViewPager no soporta layout_height = wrap_content
- Fragment.onCreateView () no se llama en viewpager después del cambio de configuración
- Manejo de PagerTitleStrip haga clic en compatibilidad Fragment-based ViewPager
- Reemplazar un fragmento / ficha en un Viewpager
Bueno, escribí un poco de solución de fuerza bruta para esto.
Mi PagerAdapter
:
public class ViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return 2; } @Override public Object instantiateItem(ViewGroup container, int position) { FrameLayout layout = new FrameLayout(container.getContext()); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); layout.setLayoutParams(layoutParams); layout.setBackgroundColor(position % 2 == 0 ? Color.RED : Color.BLUE); container.addView(layout); return layout; } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } }
(Así que el "estado" visualmente difiere en su color – es rojo en la primera posición y azul en la segunda posición)
El RecyclerViewAdapter
tiene el siguiente aspecto:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public HashMap<Integer, Integer> viewPageStates = new HashMap<>(); public RecyclerViewAdapter() {} @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { return new ViewHolder(new ViewWithViewPager(viewGroup.getContext())); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((ViewWithViewPager) holder.itemView).refreshState(position, viewPageStates.containsKey(position)? viewPageStates.get(position) : 0); } @Override public int getItemCount() { return 42; } @Override public void onViewRecycled(RecyclerView.ViewHolder holder) { ViewWithViewPager recycledViewPager = ((ViewWithViewPager)holder.itemView); viewPageStates.put(recycledViewPager.viewPosition, recycledViewPager.viewPager.getCurrentItem()); super.onViewRecycled(holder); } public class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); } } }
Es decir cada vez que ViewHolder
RecyclerView
, pasamos el estado actual del viewpager (de viewPageStates
) y su orden en el dataset de RecyclerView
. Una vez que se recicla – leemos su estado actual de la página y lo viewPageStates
en HashMap
viewPageStates
.
La última pieza – ViewWithViewPager
public class ViewWithViewPager extends FrameLayout { ViewPager viewPager; int viewPosition = 0; public ViewWithViewPager(Context context) { super(context); LayoutInflater.from(context).inflate(R.layout.item_layout, this); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new ViewPagerAdapter()); } public void refreshState(int position, int selectedPage) { viewPosition = position; viewPager.setCurrentItem(selectedPage); } }
Es decir, en refreshState
, establecemos ViewPager en la página correcta
Solución por OP.
- Anular onViewRecycled (ViewHolder viewHolder) {} dentro de su RecyclerView.Adapter
- Utilice un HashMap para almacenar la posición del ViewPager en el RecyclerView y la correspondiente página actual seleccionada del ViewPager.
- Dentro del método onViewRecycled () introduzca los valores en el HashMap creado anteriormente.
- En el método onBindViewHolder () cargue el estado / página guardado del ViewPager desde el HashMap utilizando la posición y establezca el estado / página guardado en ViewPager utilizando el método setCurrentItem ().
Gracias a Konstantin y atabouraya.
- Android en la aplicación de facturación compra de prueba se bloquea Play Store
- Android: ¿La manera más fácil de hacer que un WebView muestre un mapa de bits?