Android ViewPager con RecyclerView funciona incorrectamente dentro de BottomSheet
Cuando intento a la lista de desplazamiento, a veces esto funciona incorrecto – BottomSheet intercepta el evento de desplazamiento y se esconde.
Cómo reproducir esto:
- ¿Qué es la contraparte de RecyclerView.Adapter de ListView.Adpater.isEnabled ()
- ¿Cuáles son las ventajas de RecyclerView en comparación con ListView?
- Cómo hacer la primera imagen más grande en Gridlayout?
- (Smooth) ScrollToPosition no funciona correctamente con RecyclerView
- La transición de elementos compartidos no tiene el comportamiento esperado
- Hoja inferior abierta
- Cambiar una página de ViewPager
- Trate de desplazarse por la lista
Resultado: BottomSheet se ocultará.
Aquí está el ejemplo de código:
Compile 'com.android.support:design:23.4.0'
MainActivity.java
package com.nkdroid.bottomsheetsample; import android.os.Bundle; import android.support.design.widget.BottomSheetBehavior; import android.support.design.widget.TabLayout; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private BottomSheetBehavior behavior; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button btnView = (Button) findViewById(R.id.btnView); btnView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { behavior.setState(BottomSheetBehavior.STATE_EXPANDED); } }); final View bottomSheet = findViewById(R.id.bottom_sheet); behavior = BottomSheetBehavior.from(bottomSheet); final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new MyPagerAdapter()); final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); } private class MyPagerAdapter extends PagerAdapter { @Override public int getCount() { return 15; } @Override public Object instantiateItem(final ViewGroup container, final int position) { final RecyclerView recyclerView = new RecyclerView(MainActivity.this); recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this)); recyclerView.setAdapter(new ItemAdapter()); container.addView(recyclerView); return recyclerView; } @Override public boolean isViewFromObject(final View view, final Object object) { return view.equals(object); } @Override public void destroyItem(final ViewGroup container, final int position, final Object object) { container.removeView((View) object); } @Override public CharSequence getPageTitle(final int position) { return String.valueOf(position); } } public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> { @Override public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) { return new ViewHolder(new TextView(MainActivity.this)); } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { } @Override public int getItemCount() { return 100; } public class ViewHolder extends RecyclerView.ViewHolder { public TextView textView; public ViewHolder(final View itemView) { super(itemView); textView = (TextView) itemView; } } } }
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout android:id = "@+id/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" android:background = "#a3b1ef" android:fitsSystemWindows = "true" tools:context = ".ui.MainActivity" > <Button android:id = "@+id/btnView" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:text = "Show view" app:layout_behavior = "@string/appbar_scrolling_view_behavior" /> <LinearLayout android:id = "@+id/bottom_sheet" android:layout_width = "match_parent" android:layout_height = "400dp" android:background = "#fff" android:gravity = "center" android:orientation = "vertical" app:layout_behavior = "@string/bottom_sheet_behavior" > <android.support.design.widget.TabLayout android:id = "@+id/tabs" android:layout_width = "match_parent" android:layout_height = "wrap_content" app:tabMode = "scrollable" /> <android.support.v4.view.ViewPager android:id = "@+id/viewPager" android:layout_width = "match_parent" android:layout_height = "match_parent" /> </LinearLayout> </android.support.design.widget.CoordinatorLayout>
¿Alguna idea para una solución?
- No se puede colocar la vista debajo de RecyclerView
- RecyclerView onItemClicked devolución de llamada
- RecyclerView RecyclerViewDataObserver no estaba registrado
- ¿Cómo agregar un simple encabezado 8dp / pie de página a RecyclerView de Android?
- Cargando imagen con deslizamiento es lento
- Recylerview no visible dentro de scrollview o nestedScrollview
- ¿Cómo manejar los contadores de cuenta regresiva múltiples en RecyclerView?
- Uso de RecyclerView con tarjeta
Me encontré con la misma limitación, pero fueron capaces de resolverlo.
La razón del efecto que describió es que BottomSheetBehavior
(a partir de v24.2.0) sólo admite un niño desplazable que se identifica durante el diseño de la siguiente manera:
private View findScrollingChild(View view) { if (view instanceof NestedScrollingChild) { return view; } if (view instanceof ViewGroup) { ViewGroup group = (ViewGroup) view; for (int i = 0, count = group.getChildCount(); i < count; i++) { View scrollingChild = findScrollingChild(group.getChildAt(i)); if (scrollingChild != null) { return scrollingChild; } } } return null; }
Puede ver que encuentra esencialmente el primer niño que se desplaza con DFS.
He mejorado ligeramente esta implementación y montado una pequeña biblioteca , así como una aplicación de ejemplo. Puede encontrarlo aquí: https://github.com/laenger/ViewPagerBottomSheet
Simplemente agregue la URL de repo de maven a su build.gradle:
repositories { maven { url "https://raw.github.com/laenger/maven-releases/master/releases" } }
Agregue la biblioteca a las dependencias:
dependencies { compile "biz.laenger.android:vpbs:0.0.2" }
Use ViewPagerBottomSheetBehavior
para la vista inferior de la hoja:
app:layout_behavior="@string/view_pager_bottom_sheet_behavior"
Configurar cualquier ViewPager anidado dentro de la hoja inferior:
BottomSheetUtils.setupViewPager(bottomSheetViewPager)
(Esto también funciona cuando ViewPager es la vista inferior de la hoja y para otras ViewPagers anidadas)
- ¿Existen alternativas a Google Cloud Messaging para las compilaciones personalizadas de Android?
- ¿Cómo puedo asegurar que el controlador de otro hilo no sea nulo antes de llamarlo?