Estamos sufriendo un problema muy extraño con ViewPager aquí. Incrustamos listas en cada página de ViewPager y activamos notifyDataSetChanged tanto en el adaptador de lista como en el adaptador de buscapersonas al actualizar los datos de lista.
Lo que observamos es que, en ocasiones, la página no actualiza su árbol de vistas, es decir, permanece en blanco o, en ocasiones, incluso desaparece al paginarse. Al desplazarse varias veces hacia adelante y hacia atrás, el contenido reaparecerá repentinamente. Parece que a Android le falta una actualización de vista aquí. También noté que al depurar con el visor de jerarquía, seleccionar una vista siempre hará que vuelva a aparecer, aparentemente porque el visor de jerarquía obliga a la vista seleccionada a volver a dibujarse.
Sin embargo, no pude hacer que esto funcione programáticamente; invalidar la vista de lista, o incluso todo el paginador de vista, no tuvo ningún efecto.
Esto es con la biblioteca compatibilidad-v4_r7. También traté de usar la última revisión, ya que pretende solucionar muchos problemas relacionados con la visualización del buscapersonas, pero empeoró las cosas (por ejemplo, los gestos se interrumpieron para que a veces ya no me dejaran pasar por todas las páginas).
¿Alguien más se encuentra con estos problemas también o tiene una idea de lo que podría estar causando esto?
fuente
Si
ViewPager
se establece dentro de un Fragmento con aFragmentPagerAdapter
, utilícelo engetChildFragmentManager()
lugar degetSupportFragmentManager()
como parámetro para inicializar suFragmentPagerAdapter
.mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
En vez de
mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
fuente
getItem()
unFragmentPagerAdapter
que estaba anidado en un Fragmento recreado.Tuve exactamente el mismo problema, pero en realidad destruí la vista en destroyItem (pensé). Sin embargo, el problema fue que lo destruí usando
viewPager.removeViewAt(index);
insted ofviewPager.removeView((View) object);
Incorrecto:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeViewAt(position); }
Derecho:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeView((View) object); }
fuente
ViewPager intenta hacer cosas inteligentes en torno a la reutilización de elementos, pero requiere que devuelva nuevas posiciones de elementos cuando las cosas han cambiado. Intente agregar esto a su PagerAdapter:
public int getItemPosition (Object object) { return POSITION_NONE; }
Básicamente, le dice a ViewPager que todo ha cambiado (y lo obliga a volver a crear una instancia de todo). Eso es lo único en lo que se me ocurre la cabeza.
fuente
return POSITION_NONE;
,forces it to re-instantiate everything
pero en mi caso no quiero volver a crear una instancia de todo , entonces ¿sería posible eliminarview
sin borrar las cosas existentes?Probé demasiadas soluciones pero
viewPager.post()
funcionó inesperadamentemAdapter = new NewsVPAdapter(getContext(), articles); viewPager.post(new Runnable() { @Override public void run() { viewPager.setAdapter(mAdapter); } });
fuente
La biblioteca de soporte de Android tiene una actividad de demostración que incluye un ViewPager con un ListView en cada página. Probablemente debería echarle un vistazo y ver qué hace.
En Eclipse (con Android Dev Tools r20):
New > Android Sample Project
Support4Demos
Android Tools > Add Support Library
Fragment
y luegoPager
El código para esto está en
src/com.example.android.supportv4.app/FragmentPagerSupport.java
. ¡Buena suerte!fuente
Me encontré con esto y tuve problemas muy similares. Incluso lo pregunté en stack overflow.
Para mí, en el padre del padre de mi vista, alguien subclasificó
LinearLayout
y anulórequestLayout()
sin llamarsuper.requestLayout()
. Esto impidióonMeasure
yonLayout
de ser llamado en mi ViewPager (aunque hierarchyviewer llamadas de forma manual estos). Si no se miden, aparecerán en blanco en ViewPager.Así que revisa tus vistas de contenido. Asegúrese de que tengan una subclase de View y no anulen ciegamente requestLayout ni nada similar.
fuente
Tuve el mismo problema, que tiene algo que ver con
ListView
(porque mi vista vacía se muestra bien si la lista está vacía). Solo llamérequestLayout()
a la problemáticaListView
. ¡Ahora dibuja bien!fuente
Me encontré con este mismo problema cuando usaba ViewPager y FragmentStatePagerAdapter. Intenté usar un controlador con un retraso de 3 segundos para llamar a invalidate () y requestLayout () pero no funcionó. Lo que funcionó fue restablecer el color de fondo de viewPager de la siguiente manera:
MyFragment.java
private Handler mHandler; private Runnable mBugUpdater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = new ViewPager(getActivity()); //...Create your adapter and set it here... mHandler = new Handler(); mBugUpdater = new Runnable(){ @Override public void run() { mVp.setBackgroundColor(mItem.getBackgroundColor()); mHandler = null; mBugUpdater = null; } }; mHandler.postDelayed(mBugUpdater,50); return rootView; } @Override public void onPause() { if(mHandler != null){ //Remove the callback if it hasn't triggered yet mHandler.removeCallbacks(mBugUpdater); mHandler = null; mBugUpdater = null; } super.onPause(); }
fuente
Tuve un problema con los mismos síntomas, pero una causa diferente que resultó ser un error tonto de mi parte. Pensé en agregarlo aquí en caso de que ayude a alguien.
Tenía un ViewPager usando FragmentStatePagerAdapter que solía tener dos fragmentos, pero luego agregué un tercero. Sin embargo, olvidé que el límite predeterminado de páginas fuera de la pantalla es 1, por lo que, cuando cambiaba al nuevo tercer fragmento, el primero se destruía y luego se recreaba después de volver a cambiar. El problema era que mi actividad se encargaba de notificar a estos fragmentos para inicializar su estado de IU. Esto pasó a funcionar cuando la actividad y los ciclos de vida de los fragmentos eran los mismos, pero para solucionarlo tuve que cambiar los fragmentos para inicializar su propia IU durante su ciclo de vida de inicio. Al final, también terminé cambiando setOffscreenPageLimit a 2 para que los tres fragmentos se mantuvieran vivos en todo momento (seguro en este caso, ya que no consumían mucha memoria).
fuente
Tuve un problema similar. Guardo en caché las vistas porque solo necesito 3 vistas en formato
ViewPager
. Cuando me deslizo hacia adelante, todo está bien, pero cuando empiezo a deslizarme hacia atrás ocurre un error, dice que "mi vista ya tiene un padre". La solución es eliminar los elementos innecesarios manualmente.@Override public Object instantiateItem(ViewGroup container, int position) { int localPos = position % SIZE; TouchImageView view; if (touchImageViews[localPos] != null) { view = touchImageViews[localPos]; } else { view = new TouchImageView(container.getContext()); view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); touchImageViews[localPos] = view; } view.setImageDrawable(mDataModel.getPhoto(position)); Log.i(IRViewPagerAdpt.class.toString(), "Add view " + view.toString() + " at pos: " + position + " " + localPos); if (view.getParent() == null) { ((ViewPager) container).addView(view); } return view; } @Override public void destroyItem(ViewGroup container, int position, Object view) { // ((ViewPager) container).removeView((View) view); Log.i(IRViewPagerAdpt.class.toString(), "remove view " + view.toString() + " at pos: " + position); } .................. private static final int SIZE = 3; private TouchImageView[] touchImageViews = new TouchImageView[SIZE];
fuente
Para mí, el problema fue volver a la actividad después de que se eliminó el proceso de la aplicación. Estoy usando un adaptador de localizador de vista personalizado modificado de las fuentes de Android. El localizador de vista está integrado directamente en la actividad.
Vocación
viewPager.setCurrentItem(position, true);
(con animación) después de configurar los datos y notifyDataSetChanged () parece funcionar, pero si el parámetro se establece en falso, no lo hace y el fragmento está en blanco. Este es un caso marginal que puede ser de ayuda para alguien.
fuente