Buscar..


Introducción

ViewPager es un administrador de diseño que permite al usuario voltear hacia la izquierda y hacia la derecha a través de las páginas de datos. Se usa con más frecuencia junto con Fragmento, que es una forma conveniente de suministrar y administrar el ciclo de vida de cada página.

Observaciones

Una cosa importante a tener en cuenta sobre el uso de ViewPager es que hay dos versiones diferentes de FragmentPagerAdapter y FragmentStatePagerAdapter .

Si usa android.app.Fragment Fragmentos nativos con FragmentPagerAdapter o FragmentStatePagerAdapter, debe usar las versiones de la biblioteca de soporte del adaptador v13, es decir, android.support.v13.app.FragmentStatePagerAdapter .

Si está utilizando android.support.v4.app.Fragment support library Fragments con un FragmentPagerAdapter o FragmentStatePagerAdapter, debe usar las versiones de la biblioteca de soporte v4 del adaptador, es decir, android.support.v4.app.FragmentStatePagerAdapter .

Uso básico de ViewPager con fragmentos.

Un ViewPager permite mostrar múltiples fragmentos en una actividad que se puede navegar girando hacia la izquierda o hacia la derecha. Un ViewPager debe ser alimentado de Vistas o Fragmentos usando un PagerAdapter .

Sin embargo, existen otras dos implementaciones específicas que le resultarán más útiles en caso de utilizar Fragments que son FragmentPagerAdapter y FragmentStatePagerAdapter . Cuando se debe crear una instancia de un Fragmento por primera vez, se getItem(position) para cada posición que se necesite instanciar. El método getCount() devolverá el número total de páginas para que ViewPager sepa cuántos Fragmentos deben mostrarse.

Tanto FragmentPagerAdapter como FragmentStatePagerAdapter mantienen un caché de los fragmentos que el ViewPager deberá mostrar. Por defecto, el ViewPager intentará almacenar un máximo de 3 Fragmentos que corresponden al Fragmento actualmente visible, y los que están al lado de la derecha y la izquierda. Además, FragmentStatePagerAdapter mantendrá el estado de cada uno de sus fragmentos.

Tenga en cuenta que ambas implementaciones asumen que sus fragmentos mantendrán sus posiciones, por lo que si mantiene una lista de los fragmentos en lugar de tener un número estático de ellos, como puede ver en el método getItem() , deberá crear una subclase de PagerAdapter y anular al menos los métodos instantiateItem() , destroyItem() y getItemPosition() .

Solo agregue un ViewPager en su diseño como se describe en el ejemplo básico :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout> 
    <android.support.v4.view.ViewPager
        android:id="@+id/vpPager"> 
    </android.support.v4.view.ViewPager>
</LinearLayout>

Luego, defina el adaptador que determinará cuántas páginas existen y qué fragmento mostrar para cada página del adaptador.

public class MyViewPagerActivity extends AppCompatActivity {
    private static final String TAG = MyViewPagerActivity.class.getName();

    private MyPagerAdapter mFragmentAdapter;
    private ViewPager mViewPager;

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

        //Apply the Adapter
        mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());    
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(mFragmentAdapter);
    }

    private class MyPagerAdapter extends FragmentPagerAdapter{

        public MyPagerAdapter(FragmentManager supportFragmentManager) {
            super(supportFragmentManager);
        }

        // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new Fragment1();

                case 1:
                    return new Fragment2();

                case 2:
                    return new Fragment3();

                default:
                    return null;
            }
        }

        // Returns total number of pages    
        @Override
        public int getCount() {
            return 3;
        }

    }
}
3.2.x

Si está utilizando android.app.Fragment , debe agregar esta dependencia:

compile 'com.android.support:support-v13:25.3.1'

Si está utilizando android.support.v4.app.Fragment , debe agregar esta dependencia:

compile 'com.android.support:support-fragment:25.3.1'

ViewPager con TabLayout

Se puede utilizar un TabLayout para una navegación más fácil.
Puede configurar las pestañas para cada fragmento en su adaptador usando el método TabLayout.newTab() pero hay otro método más conveniente y más fácil para esta tarea que es TabLayout.setupWithViewPager() .

Este método se sincronizará creando y eliminando pestañas de acuerdo con el contenido del adaptador asociado con su ViewPager cada vez que lo llame.
Además, establecerá una devolución de llamada por lo que cada vez que el usuario pase la página, se seleccionará la pestaña correspondiente.

Solo define un diseño

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabMode="scrollable" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1" />

</LinearLayout>

Luego implemente el FragmentPagerAdapter y aplíquelo al ViewPager :

public class MyViewPagerActivity extends AppCompatActivity {
    private static final String TAG = MyViewPagerActivity.class.getName();

    private MyPagerAdapter mFragmentAdapter;
    private ViewPager mViewPager;
    private TabLayout mTabLayout;

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

        // Get the ViewPager and apply the PagerAdapter
        mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());    
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(mFragmentAdapter);

        // link the tabLayout and the viewpager together
        mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
        mTabLayout.setupWithViewPager(mViewPager);
    }

    private class MyPagerAdapter extends FragmentPagerAdapter{

        public MyPagerAdapter(FragmentManager supportFragmentManager) {
            super(supportFragmentManager);
        }

         // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new Fragment1();

                case 1:
                    return new Fragment2();

                case 2:
                    return new Fragment3();

                default:
                    return null;
            }
        }
        
        // Will be displayed as the tab's label
        @Override
        public CharSequence getPageTitle(int position) {
            switch(position) {
                case 0:
                    return "Fragment 1 title";

                case 1:
                    return "Fragment 2 title";

                case 2:
                    return "Fragment 3 title";

                default:
                    return null;
            }
        }

        // Returns total number of pages 
        @Override
        public int getCount() {
            return 3;
        }

    }
}

ViewPager con PreferenceFragment

Hasta hace poco, el uso de android.support.v4.app.FragmentPagerAdapter impediría el uso de PreferenceFragment como uno de los fragmentos utilizados en FragmentPagerAdapter.

Las últimas versiones de la biblioteca de soporte v7 ahora incluyen la clase PreferenceFragmentCompat , que funcionará con un ViewPager y la versión v4 de FragmentPagerAdapter.

Fragmento de ejemplo que extiende PreferenceFragmentCompat :

import android.os.Bundle; 
import android.support.v7.preference.PreferenceFragmentCompat; 
import android.view.View; 
 
public class MySettingsPrefFragment extends PreferenceFragmentCompat { 
  
    public MySettingsPrefFragment() { 
        // Required empty public constructor 
    } 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        addPreferencesFromResource(R.xml.fragment_settings_pref); 
    } 
 
    @Override 
    public void onCreatePreferences(Bundle bundle, String s) { 
 
    } 
}

Ahora puede usar este fragmento en una subclase android.support.v4.app.FragmentPagerAdapter :

private class PagerAdapterWithSettings extends FragmentPagerAdapter {

    public PagerAdapterWithSettings(FragmentManager supportFragmentManager) {
        super(supportFragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0:
                return new FragmentOne();

            case 1:
                return new FragmentTwo();

            case 2:
                return new MySettingsPrefFragment();

            default:
                return null;
        }
    }
    
    // .......

}

Agregar un ViewPager

Asegúrese de que la siguiente dependencia se agregue al archivo build.gradle su aplicación en las dependencias:

compile 'com.android.support:support-core-ui:25.3.0'

Luego agregue el ViewPager a su diseño de actividad:

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

Luego define tu PagerAdapter :

public class MyPagerAdapter extends PagerAdapter {

    private Context mContext;

    public CustomPagerAdapter(Context context) {
        mContext = context;
    }

    @Override
    public Object instantiateItem(ViewGroup collection, int position) {
 
        // Create the page for the given position. For example:
        LayoutInflater inflater = LayoutInflater.from(mContext);
        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.xxxx, collection, false);
        collection.addView(layout);
        return layout;
    }

    @Override
    public void destroyItem(ViewGroup collection, int position, Object view) {
        // Remove a page for the given position. For example:
        collection.removeView((View) view);
    }

    @Override
    public int getCount() {
        //Return the number of views available.
        return numberOfPages;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        // Determines whether a page View is associated with a specific key object
        // as returned by instantiateItem(ViewGroup, int). For example:
        return view == object;
    }    
}

Finalmente configure el ViewPager en su actividad:

public class MainActivity extends AppCompatActivity {

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

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new MyPagerAdapter(this));
    }
}

ViewPager con un indicador de puntos

ViewPager con un indicador de puntos

Todo lo que necesitamos es: ViewPager , TabLayout y 2 dibujables para puntos seleccionados y predeterminados.

En primer lugar, debemos agregar TabLayout a nuestro diseño de pantalla y conectarlo con ViewPager . Podemos hacer esto de dos maneras:


TabLayout anidado en ViewPager

<android.support.v4.view.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</android.support.v4.view.ViewPager>

En este caso, TabLayout se conectará automáticamente con ViewPager , pero TabLayout estará al lado de ViewPager , no sobre él.


TabLayout separado

<android.support.v4.view.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

En este caso, podemos poner TabLayout cualquier lugar, pero tenemos que conectar TabLayout con ViewPager programáticamente

ViewPager pager = (ViewPager) view.findViewById(R.id.photos_viewpager);
PagerAdapter adapter = new PhotosAdapter(getChildFragmentManager(), photosUrl);
pager.setAdapter(adapter);

TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(pager, true);

Una vez que creamos nuestro diseño, tenemos que preparar nuestros puntos. Entonces creamos tres archivos: selected_dot.xml , default_dot.xml y tab_selector.xml .


selected_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@color/colorAccent"/>
        </shape>    
    </item>
</layer-list>

default_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@android:color/darker_gray"/>
        </shape>    
    </item>
</layer-list>

tab_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/selected_dot"
          android:state_selected="true"/>

    <item android:drawable="@drawable/default_dot"/>
</selector>

Ahora necesitamos agregar solo 3 líneas de código a TabLayout en nuestro diseño xml y listo.

app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"

Configurar OnPageChangeListener

Si necesita escuchar los cambios en la página seleccionada, puede implementar el ViewPager.OnPageChangeListener escucha ViewPager.OnPageChangeListener en el ViewPager:

viewPager.addOnPageChangeListener(new OnPageChangeListener() {
    
    // This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
    @Override
    public void onPageSelected(int position) {
         // Your code
    }
    
    // This method will be invoked when the current page is scrolled, either as part of 
    // a programmatically initiated smooth scroll or a user initiated touch scroll.
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
         // Your code
    }
    
    // Called when the scroll state changes. Useful for discovering when the user begins
    // dragging, when the pager is automatically settling to the current page, 
    // or when it is fully stopped/idle.
    @Override
    public void onPageScrollStateChanged(int state) {
         // Your code
    }
});


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow