studio - fragments android tutorial
FragmentPagerAdapter getItem no se llama (6)
No puedo reutilizar el fragmento en FragmentPagerAdapter. Usando el método destroyItem (), está eliminando el fragmento pero todavía no se llama a getItem () de nuevo. Solo hay 2 o 3 imágenes, así que estoy usando FragmentPagerAdapter en lugar de FragmentStatePagerAdapter.
public class ExamplePagerAdapter extends FragmentPagerAdapter {
ArrayList < String > urls;
int size = 0;
public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
super(fm);
urls = res;
size = urls.size();
}
@Override
public int getCount() {
if (urls == null) {
return 0;
} else {
return size;
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
FragmentManager manager = ((Fragment) object).getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove((Fragment) object);
trans.commit();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new FloorPlanFragment();
Bundle b = new Bundle();
b.putInt("p", position);
b.putString("image", urls.get(position));
Log.i("image", "" + urls.get(position));
fragment.setArguments(b);
return fragment;
}
}
Y en FragmentActivity,
pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2));
Descubrí que configurar un oyente en el diseño de tabLayout.setOnTabSelectedListener
no tabLayout.setOnTabSelectedListener
se llamara, probablemente porque solo tienen espacio para un oyente en tabLayout.setOnTabSelectedListener
lugar de una matriz de oyentes.
El uso de un FragmentStatePagerAdapter
no solucionó completamente mi problema, que era un problema similar cuando onCreateView
no se llamaba para fragmentos secundarios en el buscapersonas. De hecho, estoy anidando mi FragmentPagerAdapter
dentro de otro Fragment
por lo que el FragmentManager
se compartió en todos ellos y, por lo tanto, conserva las instancias de los fragmentos anteriores. La solución fue, en su lugar, alimentar una instancia de getChildFragmentManager
al constructor de FragmentPagerAdapter
en mi fragmento de host. Algo como...
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());
El método getChildFragmentManager()
es accesible a través de un fragmento y esto funcionó para mí porque devuelve un FragmentManager
privado para ese fragmento específicamente para situaciones en las que se necesitan fragmentos de anidación. ¡Espero que esto ayude a alguien que pueda estar teniendo el mismo problema que yo!
- Sin embargo, tenga en cuenta que para usar
getChildFragmentManager()
su versión mínima de la API debe tener al menos17 (4.2)
, por lo que puede arrojar una llave en sus engranajes. Por supuesto, si está utilizando fragmentos de la biblioteca de soporte v4, debería estar bien.
Hay dos escenarios diferentes: 1.) Tiene el mismo diseño para cada buscapersonas: en ese caso, será mejor si amplía su adaptador personalizado por PagerAdapter y devuelve un diseño único.
2.) Usted tiene un diseño diferente para cada buscapersonas: en ese caso, será mejor si extiende su adaptador personalizado mediante FragmentStatePagerAdapter y devuelve diferentes fragmentos para cada busca.
Hice lo que @kanika y @ Jraco11 habían publicado, pero todavía tenía el problema.
Entonces, después de muchos cambios, encontré uno que funcionó para mí y se agregó a mi FragmentPagerAdapter el siguiente código:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
De acuerdo con lo que leí, getItemPosition se usa para notificar a ViewPager si desea o no actualizar un elemento, y para evitar actualizaciones si los elementos en las posiciones visibles no han cambiado.
KISS Respuesta:
Uso simple FragmentStatePagerAdapter lugar de FragmentPagerAdapter .
Obtuve la respuesta. Primero pensé en eliminar esta pregunta ya que estoy cometiendo un error muy tonto, pero esta respuesta ayudará a alguien que enfrenta el mismo problema que en lugar de FragmentPagerAdapter
, use FragmentStatePagerAdapter
.
Como @BlackHatSamurai mencionó en el comentario:
La razón por la que esto funciona es porque
FragmentStatePagerAdapter
destruye como Fragmentos que no se están utilizando.FragmentPagerAdapter
no lo hace.
Anular long getItemId (int position)
FragmentPagerAdapter
almacena en caché los fragmentos que crea usando getItem
. Estaba enfrentando el mismo problema, incluso después de llamar a notifyDataSetChanged()
getItem
no se estaba llamando.
Esto es realmente una característica y no un error. getItemId
anular getItemId
para poder reutilizar correctamente sus fragmentos. Como está eliminando fragmentos, sus posiciones están cambiando. Como se menciona en los documentos:
long getItemId (int position)
Devuelve un identificador único para el artículo en la posición dada.
La implementación predeterminada devuelve la posición dada. Las subclases deben anular este método si las posiciones de los elementos pueden cambiar.
Solo proporcione una identificación única a cada fragmento y listo.
Usar un FragementStatePagerAdapter
o devolver POSITION_NONE
en int getItemPosition (Object object)
es incorrecto. No obtendrás ningún almacenamiento en caché.