ViewPager tiene datos de offset incorrectos después de girar la pantalla cuando la página actual no es la primera
Estructura de la aplicación:
Mi aplicación tiene una FragmentActivity
única, y que FragmentActivity
alberga un Fragment
que alberga un ViewPager
. El ViewPager
tiene un adaptador que subclases FragmentStatePagerAdapater
, y que el adaptador reemplaza getItem()
para devolver un nuevo Fragmento basado en la posición; getCount()
se establece en devolver siempre 2.
El problema:
La aplicación funciona perfectamente hasta que suceda cualquiera de dos cosas: Se produce una rotación cuando ViewPager muestra el segundo fragmento, o si, en onResume()
, se le dice al ViewPager que se desplace a una página que no sea la primera. Por lo que puedo decir, estos escenarios son idénticos. Cuando se produce uno de estos eventos, se ha detenido el desplazamiento y el Fragmento visible es el segundo de los fragmentos que gestiona ViewPager, se llama a la devolución de llamada onPageScrolled(int, float, int)
con el argumento 'position' en '0' (Debe ser 1) y el argumento 'positionOffset' establecido en '1' (que está fuera del intervalo [0,1) como se prometió en los documentos). Hice algunas exploraciones en el código de ViewPager y descubrí que la función boolean pageScrolled(int xpos)
pasa de ser llamada con valores en el rango de [0,940] (0 en la primera página y luego 940 en la segunda) a ser llamado Con valores en el rango [-940,0] (-940 en el primero, 0 en el segundo). Si ViewPager se restableció a pensar que la segunda página era la primera página, entonces esto realmente tiene sentido (una especie de), aunque no es en absoluto lo que quiero.
- Fragmento anterior visible bajo el nuevo fragmento
- ¿Es posible acceder al Fragmento actual que está siendo visualizado por un ViewPager?
- ViewPager dentro de Fragmento no muestra a pesar de usar getChildFragmentManager () al construir FragmentPagerAdapter
- Viewpager muestra página incorrecta
- ¿Cómo eliminar las pestañas de Android ViewPager divider?
Algunos Código:
ViewPagerFragment (aloja el ViewPager). MyViewPager es sólo una copia / pegada de ViewPager de la biblioteca de soporte; Quería imprimir algunos de los datos de sus métodos privados.
public class ViewPagerFragment extends Fragment implements MyViewPager.OnPageChangeListener{ @InjectView(R.id.view_pager) MyViewPager viewPager; @DebugLog public ViewPagerFragment() { setRetainInstance(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_view_pager, container, false); ButterKnife.inject(this,view); Log.d("onCreateView()","ViewPagerFragment = "+this.toString()); return view; } @Override public void onResume() { super.onResume(); setupPager(); } void setupPager(){ if(viewPager != null) { if (viewPager.getAdapter() == null) { viewPager.setAdapter(new MyFragmentAdapter(getChildFragmentManager())); } viewPager.setOnPageChangeListener(this); viewPager.setPageMargin(40); } } @Override @DebugLog public void onDestroyView() { super.onDestroyView(); viewPager.setOnPageChangeListener(null); ButterKnife.reset(this); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if(positionOffset == 1f){ Log.d("onPageScrolled","position offset == 1 and position == "+position+". That's bad!"); } else if(position == 1){ Log.d("onPageScrolled","position offset == "+positionOffset+" and position == 1. That's good!"); } } public static class MyFragmentAdapter extends FragmentStatePagerAdapter{ public MyFragmentAdapter(FragmentManager fm) { super(fm); } @Override @DebugLog public Fragment getItem(int position) { return PageFragment.newInstance(position); } @Override public int getCount() { return 2; } }
}
Mi pregunta, en caso de que no esté implícita, es "¿Qué he hecho para estropear mi ViewPager, y cómo puedo solucionarlo?" Eliminar la llamada setRetainInstance()
obviamente restablecerá las cosas a normal, pero luego pierdo mi 'lugar' en ViewPager. La eliminación de la llamada setRetainInstance()
y, a continuación, utilizar Bundle savedInstanceState
para conservar la posición ViewPager también no funciona (como se mencionó en la parte superior de mi publicación).
¡Gracias por adelantado!
- El desplazamiento de ViewPager no funciona con RecyclerView
- ViewPager + FragmentStatePageAdapter: ¿qué significa esta advertencia "no actualizada en línea"?
- Cambiar el color de desplazamiento excesivo de ViewPager
- Fragment.onCreateView () no se llama en viewpager después del cambio de configuración
- ViewPager Parpadea al tocar en el área vacía
- Utilizar un fragmento en un ViewPager varias veces
- ViewPager con fragmentos anidados?
- Cómo limitar los cambios de página de ViewPager a uno por gesto
Parece que hay un error en ViewPager después de la rotación.
Calculo el scrollX (offset) de la página actual, y siempre es 0 cuando se hace una página de desplazamiento.
Sin embargo, viene a 1 o X (alrededor del ancho de página, 938 ~ 9 si el ancho de página es 940) después de rotación.
He tenido algunos problemas en onPageScrolled
cuando el dispositivo gira, y he resuelto estos llamando a setAdapter
nuevo en callback de rotación como onConfigurationChanged
.
Aquí hay algunos bloques de código. Device
es mi clase personalizada.
public void configOnOrientationChange() { if (Device.isPortrait(getContext())) { configOnPortraitOrientation(); } else if (Device.isLandscape(getContext())) { configOnLandscapeOrientation(); } int currentItem = mViewPager.getCurrentItem(); if (mPagerAdapter != null) { mViewPager.setAdapter(mPagerAdapter); mViewPager.setCurrentItem(currentItem); } }
Espero que esto ayude.
- Cómo utilizar android ndk r9b para compilar FFMPEG para Android
- Longitud del campo de entrada de contraseña = 0 en relleno automático (cromo android)