2012-08-28 16 views
22

Parece que cuando se utiliza un ViewPager, el oyente onPageSelected no se llama para el primer problema de la misma página que this.ViewPager onPageSeleccionado para la primera página

He cierta lógica que puebla algunos elementos de interfaz de usuario más caras de la página seleccionada en ese momento y esto funciona cuando se cambia la página, pero it doesn't work for the first page.

Si fijo el elemento actual después de que el oyente, la devolución de llamada es despedido de la primera página, pero la vista no se ha inicializado todavía, así que no puede manipularlo:

// Inside PagerAdapter.instantiateItem 

ViewHolder vh = new ViewHolder(); 
cursor.moveToPosition(position); 
vh.view = adapter.newView(context, cursor, null); 
// Set position as tag so we can retrieve it with findViewByTag 
vh.view.setTag(position); 

((ViewPager) collection).addView(vh.view,0);  

return vh; 

// Inside MyActivity.onCreate 

pagerAdapter = new SingleMessagePagerAdapter(this, cursor); 
pager = (ViewPager)findViewById(R.id.message_pager); 
pager.setAdapter(pagerAdapter); 
pager.setOnPageSelectedListener(this); 
pager.setCurrentItem(selectedItem); 

// Inside MyActivity.onPageSelected 

// Retrieve tagged view 
View view = pager.findViewWithTag(position); 

Aquí view termina siendo nula porque PagerAdapter.instantiateItem todavía no se ha ejecutado. Así que supongo que mi pregunta es, ¿en qué punto del ciclo de vida de la actividad puedo estar seguro de que ViewPager ha inicializado la vista? Intenté hacer esto dentro de Activity.onAttachedToWindow y Activity.onResume, pero parece que ambos se dispararon antes de PagerAdapter.instantiateItem.

Respuesta

2

intente utilizar fragmentos!

public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter() { 
     super(getSupportFragmentManager()); 
    } 

    @Override 
    public Fragment getItem(int i) { 
     Fragment fr = null; 
     if (i==0) 
      fr = new sec0frag(); 
     else if (i==1) 
      fr = new sec1frag(); 
     else if (i==2) 
      fr = new sec2frag(); 
     return fr; 
    } 

    @Override 
    public int getCount() { 
     return 3; 
    } 
} 

y crear 3 clases de fragmentos

por ejemplo :

public static class sec0frag extends Fragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
        // here is initialize for first time to view pages.! 
     } 
    } 
+0

Esto debería funcionar, pero lo que si tiene que desplazarse por una lista de páginas cuyo número no está predefinido? ¿Como una lista de elementos que se obtienen de la web y cada uno de ellos debe mostrarse en cada uno de estos buscapersonas uno por uno? –

+0

defina getCount() en FragmentPagerAdapter dinámicamente o intente habilitar el bucle en ViewPager !! – SSKahani

5

Me pregunto por qué no solo tiene la lógica que menciona en el Fragmento en sí, en lugar de la Actividad de alojamiento. ViewPager almacena un par de fragmentos a cada lado del actual para que estén configurados en segundo plano y listos para usar cuando el usuario se desliza hacia ellos. Poner la lógica en onPageSelected significaría pasar por alto esta funcionalidad y no hacer el trabajo pesado hasta que el usuario se deslice hacia la página.

Suponiendo que por alguna razón no puede hacer lo anterior, ¿por qué no utilizar un Interface with a callback function. Desencadena la devolución de llamada en la función onCreateView del fragmento para que la actividad sepa que está completamente instanciada.

1

Mi solución fue ampliar el adaptador de buscapersonas y crear una interfaz dentro de él. Luego, haga que el adaptador llame a la interfaz solo una vez después de crear el adaptador. Devolución de llamada de la interfaz interna puede llamar al método de la página de cambio sin tener nullpointerexception. Agregue esta clase a su proyecto y amplíe su adaptador desde allí. No te olvides de configurar el oyente con el adaptador antes de configurar el adaptador a viewpager. clase adaptador a continuación: Código

public abstract class ExtendedPagerAdapter extends FragmentPagerAdapter { 

private boolean instantiated; 
private AdapterListener adapterListener; 

public interface AdapterListener { 
    void onAdapterInstantiated(); 
} 

public ExtendedPagerAdapter(FragmentManager fragmentManager) { 
    this(fragmentManager, null); 
} 

public ExtendedPagerAdapter(FragmentManager fragmentManager, AdapterListener adapterListener) { 
    super(fragmentManager); 
    this.adapterListener = adapterListener; 
    instantiated = false; 
} 

@Override 
public void finishUpdate(ViewGroup container) { 
    super.finishUpdate(container); 
    if (!instantiated) { 
     instantiated = true; 
     if (adapterListener != null) { 
      adapterListener.onAdapterInstantiated(); 
     } 
    } 
} 

public void setAdapterInstantiatedListener(AdapterListener adapterListener) { 
    this.adapterListener = adapterListener; 
} 
} 

Actividad:

adapter = new ViewPagerAdapter(getChildFragmentManager()); 
    adapter.setAdapterInstantiatedListener(new ExtendedPagerAdapter.AdapterListener() { 
     @Override 
     public void onAdapterInstantiated() { 
      onPageSelected(viewPager.getCurrentItem()); 
     } 
    }); 

    viewPager.addOnPageChangeListener(this); 
    viewPager.setAdapter(adapter); 
Cuestiones relacionadas