¿Cómo cambiar la página de ViewPager?

150

Estoy usando ViewPager en mi aplicación y lo defino en la Actividad principal. Dentro del onCreatemétodo, cargo algunas páginas de SharedPreferences y luego lo paso a PagerAdapter:

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

El problema es que si cambiara este número en Preferencias (u otra Actividad) a otro menos que el índice de página que vi antes, mi aplicación se bloquea porque este índice está fuera de límites cuando vuelvo a la actividad con este ViewPager. Se puede solucionar simplemente cambiando la página activa de ViewPager. ¿Hay alguna forma de hacerlo?

romano
fuente

Respuestas:

394

No estoy seguro de entender completamente la pregunta, pero por el título de su pregunta, supongo que lo que está buscando es pager.setCurrentItem( num ). Eso le permite cambiar programáticamente a otra página dentro de ViewPager.

Necesitaría ver un seguimiento de la pila de logcat para ser más específico si este no es el problema.

Mark Allison
fuente
3
Sí, eso es exactamente lo que necesito. Lo configuré 0en onPausemétodo y no hay bloqueos. Gracias.
Romano
1
De hecho, hay muy poca documentación en ViewPager. +1 por eso.
Arnab Chakraborty
1
si su buscapersonas tarda mucho en cargar la página, puede usar setOffscreenPageLimit (1), porque de forma predeterminada ver la carga del buscapersonas +1 y -1 página desde la posición actual
Ajay Pandya
Esto no funciona, solo recibo un error que dice que el fragmento ya se ha agregado.
BlondeSwan
24

deslizar hacia la derecha

viewPager.arrowScroll (View.FOCUS_RIGHT);

deslizar hacia la izquierda

viewPager.arrowScroll (View.FOCUS_LEFT);

Abror Esonaliyev
fuente
corto y limpio!
dakshbhatt21
1
Casi creo que esta debería ser la respuesta aceptada. Es mucho más práctico que configurar el elemento actual.
Peter
18

Sin verificar su código, creo que lo que está describiendo es que sus páginas no están sincronizadas y tiene datos obsoletos.

Dice que está cambiando la cantidad de páginas y luego se bloquea porque está accediendo al antiguo conjunto de páginas. Esto me parece que no estás llamando pageAdapter.notifyDataSetChanged()después de cambiar tus datos.

Cuando viewPagerestá mostrando la página 3 de un conjunto de 10 páginas, y cambia a un conjunto con solo 5, luego llame notifyDataSetChanged(), lo que encontrará es que ahora está viendo la página 3 del nuevo conjunto. Si anteriormente estaba viendo la página 8 del conjunto anterior, después de colocar el nuevo conjunto y llamar notifyDataSetChanged(), verá que ahora está viendo la última página del nuevo conjunto sin fallar.

Si simplemente cambia su página actual, puede estar ocultando el problema.

RichardP
fuente
1
más 1 para notifyDataSetChanged ()
madhu527
@ Richard Me salvas el día amigo. 10000+ paranotifyDataSetChanged()
Ali
15

para cambiar a otra página, intente con este código:

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);
David Figueroa
fuente
1
¡Perfecto! Traté de usarlo sin el método postDelay y no funcionó. ¿Sabes por qué funciona con este método? ¡Gracias! :)
Georgi Koemdzhiev
La misma pregunta ... ¿por qué está cambiando el elemento con este retraso y no de otra manera?
Kalyan Raghu
@GeorgiKoemdzhiev Porque la vista aún no está terminada cuando llamasviewPager.setCurrentItem
Zohab Ali
3

Respuesta suplementaria

Originalmente tenía problemas para obtener una referencia ViewPagerde otros métodos de clase porque addOnTabSelectedListenercreaba una clase interna anónima, que a su vez requería ViewPagerque se declarara la variable final. La solución fue usar una variable miembro de clase y no usar la clase interna anónima.

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        // don't use an anonymous inner class here
        tabLayout.addOnTabSelectedListener(tabListener);

    }

    TabLayout.OnTabSelectedListener tabListener = new TabLayout.OnTabSelectedListener() {

        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    };

    // The view pager can now be accessed here, too.
    public void someMethod() {
        viewPager.setCurrentItem(0);
    }

}
Suragch
fuente