android - ViewPager con fragmentos-onPause(), onResume()?
android-viewpager (7)
Para dar una definición un poco más a los métodos en la respuesta de :
yourPager.setOnPageChangeListener(new GridViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int row, int column, float rowOffset, float columnOffset, int rowOffsetPixels, int columnOffsetPixels) {
}
@Override
public void onPageSelected(int row, int column) {
// When on page selected if position is not specific for you
// you can find your fragment or you can switch position.
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Al usar ViewPager con fragmentos, nuestros métodos onPause (), onResume () no se invocan cuando se mueve entre pestañas. ¿Hay alguna manera de que podamos descubrir el fragmento cuando nos estamos haciendo visibles o escondidos?
Lamentablemente, tengo lógica en onResume (), onPause (), como registrarme en los servicios de ubicación, que nunca se detienen al cambiar de pestaña porque onPause () nunca se llama hasta que uno sale de la aplicación completa.
Gracias
Puedes usar el método a continuación en Fragment
public void setUserVisibleHint(boolean isVisibleToUser){
}
cuando isVisibleToUser == true
, se muestra el fragmento
Si U usa la Biblioteca de soporte de Android (rev 11), puede usar getUserVisibleHint () o anular setUserVisibleHint() para capturar los cambios visibles y ocultos. Mira esta post .
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// do something when visible.
}
}
Teniendo en cuenta que las soluciones anteriores no están muy claras, así es como lo resolví gracias a Phix por su pista:
En la devolución de llamada de OnPageChange ():
Fragment old_fragment = getActiveFragment(old_position);
Fragment new_fragment = getActiveFragment(new_position);
old_f.setUserVisibleHint(false);
old_f.onPause();
new_f.setUserVisibleHint(true);
new_f.onResume();
Luego en onResume ():
if (getUserVisibleHint())
/* resume code */
y en Pausa ():
if (!getUserVisibleHint())
/* pause code */
Aquí está el código getActiveFragment, evitando buscar eso también:
return fragmentManager.findFragmentByTag("android:switcher:" + viewPagerId + ":" + position);
NB: Fragment tiene un método isVisible (), pero no parece ser muy consistente, de ahí el uso de UserVisibleHint.
EDITAR: reemplaza el UserVisibleHint por un indicador privado. ¡Trabajó mucho mejor!
Un poco tarde para la fiesta, pero en mi aplicación actual configuré OffScreenPageLimit en 1 para mi viewpager, esto significa que los fragmentos no están en la memoria caché y cada vez que la vista cambia, vuelve a cargar el fragmento actual.
ViewPager viene con la interfaz OnPageChangeListener
. Al establecer algunos indicadores para las páginas anteriores y actuales, puede emular este comportamiento.
Solución 1:
Defina un SparseArray
en los adaptadores de su ViewPagers
como a continuación. En este conjunto, mantendremos la instancia de fragmentos.
SparseArray<Fragment> registeredFragments = new SparseArray<>();
Y Override
el método instantiateItem
sus adaptadores.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
También Override
método destroyItem
de tus ViewPagers
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
Y defina un nuevo método para obtener su instancia de Fragments
ViewPager
.
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
Ahora puede implementar su lógica con ViewPager''s
OnPageChangeListener
. Aquí hay un ejemplo de cómo puede implementar ViewPageChangeListener en un onPageChangeListener
:
Definir un entero para mantener la posición actual:
int currentPos;
yourViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Empty method
}
@Override
public void onPageSelected(int position) {
// This is paused fragment.
final Fragment pausedFragment = yourAdapter.getRegisteredFragment(currentPos);
// update current position value
currentPos = position;
// This is resumed fragment
final Fragment resumedFragment = yourAdapter.getRegisteredFragment(currentPos);
}
@Override
public void onPageScrollStateChanged(int state) {
// Empty method
}
});
Finalmente, para restaurar el estado de la instancia, actualice su posición actual para mantenerse actualizado en qué posición dejó el usuario ViewPager
currentPos = yourViewPager.getCurrentItem();
Solución 2:
Para otra solución, puede encontrar sus Fragments
ViewPager
por Tag
. Puedes generar tu etiqueta con:
@NonNull
public static String generateViewPagerFragmentTag(int viewPagerId, int position) {
final StringBuilder tagBuilder = new StringBuilder();
tagBuilder.append("android:switcher:");
tagBuilder.append(viewPagerId);
tagBuilder.append(":");
tagBuilder.append(position);
return tagBuilder.toString();
}
Y encuentra tu Fragment
:
final Fragment yourFragment = getSupportFragmentManager().findFragmentByTag(generateViewPagerFragmentTag(R.id.your_viewpager, currentPos));
Editar: Hace unos años, mientras buscaba una solución para obtener el elemento actual de UserVisibleHint
probé UserVisibleHint
en Fragments
y noté que no era confiable. No estoy seguro de si es confiable o no ahora, pero aún así evito usarlo.