android - studio - Fragmento de actualización de ViewPager en deslizamiento
android viewpager fragment example (4)
Tengo un problema con el que he estado luchando durante los últimos 2 días.
Estoy construyendo una aplicación que usa ActionBar, ViewPager y FragmentPagerAdapter. El código para la Actividad, Fragmentos y FragmentPagerAdapter son exactamente los que se indican en el ejemplo de Android en http://developer.android.com/reference/android/support/v4/view/ViewPager.html
El problema al que me enfrento es - suponiendo que tengo solo 2 fragmentos en viewPager. al cambiar / deslizar entre los dos, los fragmentos no se actualizan. onResume no se llama porque el viewPager almacena en caché un mínimo de 1 fragmento a cada lado del fragmento mostrado.
Intenté usar onTabSelected para detectar cuándo se selecciona un fragmento y luego iniciar un método a partir de ese fragmento con la ayuda de una interfaz (código a continuación).
public void onTabSelected(Tab tab, FragmentTransaction ft) {
TabInfo tag = (TabInfo)tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
((IStartStop)getItem(tab.getPosition())).Start();
}
Sin embargo, cuando se utiliza el método Start, se dispara una NullPointerException cuando se intenta actualizar una vista de texto. El código del método de inicio es:
public void Start() {
TextView tv = _view.findViewById(R.id.text);
tv.setText("test");
}
La excepción se arroja en la línea:
TextView tv = _view.findViewById(R.id.text);
La interfaz IStartStop es bastante simple:
public interface IStartStop {
public void Start();
public void Stop();
}
No quiero usar notifyDataSetChanged (); con POSITION_NONE porque cada vez que deslizo un nuevo fragmento, toma unos segundos cargar los fragmentos
En este momento, los fragmentos solo incluyen una vista de texto, en el futuro tendrán una animación, por lo que es importante:
1- Solo ejecuta una animación cuando se selecciona el fragmento y no cuando se selecciona el fragmento a su lado (la forma en que ViewPager almacena en caché y reanuda los fragmentos).
2- Detenga la animación cuando el fragmento ya no esté seleccionado para evitar desperdiciar recursos del dispositivo.
Sí, ya he verificado todo lo que está disponible en Internet, pero nada parece funcionar conmigo.
¡Muchas gracias por su ayuda!
Agregue este código cuando defina Viewpager
mViewPager.setOffscreenPageLimit(0);
No se guardará ninguna vista de los fragmentos cuando cambies a otro fragmento ... así que cambiar de fragmento a otro creará el fragmento desde el principio y lo actualizará todo.
Esto afectará los cambios de una página a otra en el buscador de la vista.
OnPageChangeListener pagechangelistener =new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Logger.logMessage("Called first");
pageAdapter.notifyDataSetChanged();
indicator.setCurrentItem(arg0);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Logger.logMessage("Called second");
}
@Override
public void onPageScrollStateChanged(int arg0) {
Logger.logMessage("Called third");
}
};
myViewPager.setOnPageChangeListener(pagechangelistener);
Use esto en su adaptador de página.
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Sorprendentemente, ViewPager
no lo hace de forma "nativa" (entre otras cosas). Pero no todo esta perdido.
Primero debes modificar tus fragmentos para que solo ejecuten la animación cuando les dices que está bien y no cuando se crean instancias. De esta forma puedes jugar con el desplazamiento del viewpager (predeterminado = 3) y tener 2-3 fragmentos precargados pero no animados.
El segundo paso es crear una interfaz o similar que defina cuándo el "fragmento se ha vuelto visible".
El tercer paso sería adjuntar un nuevo OnPageScrollListener a su viewpager.
El código sigue (en el código semi-no probado):
1) Adjunte al oyente:
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int i, final float v, final int i2) {
}
@Override
public void onPageSelected(final int i) {
YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
if (fragment != null) {
fragment.fragmentBecameVisible();
}
}
@Override
public void onPageScrollStateChanged(final int i) {
}
});
2) Esta es tu interfaz:
public interface YourFragmentInterface {
void fragmentBecameVisible();
}
3) Cambia tus fragmentos para que implementen esto:
public class YourLovelyFragment extends Fragment implements YourFragmentInterface {
4) Implementar la interfaz en el fragmento
@Override
public void fragmentBecameVisible() {
// You can do your animation here because we are visible! (make sure onViewCreated has been called too and the Layout has been laid. Source for another question but you get the idea.
}
A dónde ir desde aquí?
Es posible que desee implementar un método / detector para notificar a los "otros" fragmentos que ya no son visibles (es decir, cuando uno es visible, los otros no). Pero eso puede no ser necesario.
setOnPageChangeListener ha quedado obsoleto. En su lugar, debe usar addOnPageChangeListener.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int i, final float v, final int i2) {
}
@Override
public void onPageSelected(final int i) {
YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
if (fragment != null) {
fragment.fragmentBecameVisible();
}
}
@Override
public void onPageScrollStateChanged(final int i) {
}
});