Ricerca…


introduzione

ViewPager è un gestore di layout che consente all'utente di capovolgere a sinistra ea destra tra le pagine di dati. Viene spesso utilizzato insieme a Fragment, che è un modo conveniente per fornire e gestire il ciclo di vita di ciascuna pagina.

Osservazioni

Una cosa importante da notare sull'utilizzo di ViewPager è che ci sono due diverse versioni di FragmentPagerAdapter e FragmentStatePagerAdapter .

Se si utilizza android.app.Fragment Frammenti nativi con un FragmentPagerAdapter o FragmentStatePagerAdapter, è necessario utilizzare le versioni di libreria di supporto V13 della scheda, ovvero android.support.v13.app.FragmentStatePagerAdapter .

Se si sta utilizzando la libreria di supporto android.support.v4.app.Fragment Fragments con FragmentPagerAdapter o FragmentStatePagerAdapter, è necessario utilizzare le versioni della libreria di supporto v4 dell'adattatore, ad esempio android.support.v4.app.FragmentStatePagerAdapter .

Utilizzo di base ViewPager con frammenti

Un ViewPager consente di mostrare più frammenti in un'attività che può essere esplorata ruotando verso sinistra o verso destra. Un ViewPager deve essere alimentato con Views o Fragments usando un PagerAdapter .

Esistono tuttavia due implementazioni più specifiche che troverete più utili in caso di utilizzo di Fragments che sono FragmentPagerAdapter e FragmentStatePagerAdapter . Quando un frammento deve essere istanziato per la prima volta, getItem(position) sarà chiamato per ogni posizione che ha bisogno di istanziare. Il metodo getCount() restituirà il numero totale di pagine in modo che ViewPager sappia quanti frammenti devono essere mostrati.

Sia FragmentPagerAdapter che FragmentStatePagerAdapter conservano una cache dei Frammenti che il ViewPager dovrà mostrare. Per impostazione predefinita, ViewPager tenterà di memorizzare un massimo di 3 frammenti che corrispondono al frammento attualmente visibile e quelli accanto a destra e a sinistra. Anche FragmentStatePagerAdapter manterrà lo stato di ciascuno dei tuoi frammenti.

Sappi che entrambe le implementazioni presuppongono che i tuoi frammenti manterranno le loro posizioni, quindi se mantieni un elenco dei frammenti invece di avere un numero statico di essi come puoi vedere nel metodo getItem() , dovrai creare una sottoclasse di PagerAdapter e sovrascrive almeno i metodi instantiateItem() , destroyItem() e getItemPosition() .

Basta aggiungere un ViewPager nel layout come descritto nell'esempio di base :

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

Quindi definire l'adattatore che determinerà il numero di pagine esistenti e il frammento da visualizzare per ciascuna pagina dell'adattatore.

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

Se stai usando android.app.Fragment devi aggiungere questa dipendenza:

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

Se stai usando android.support.v4.app.Fragment devi aggiungere questa dipendenza:

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

ViewPager con TabLayout

Un TabLayout può essere utilizzato per una navigazione più semplice.
È possibile impostare le schede per ciascun frammento nell'adattatore utilizzando il metodo TabLayout.newTab() , ma esiste un altro metodo più conveniente e più semplice per questa attività, che è TabLayout.setupWithViewPager() .

Questo metodo si sincronizza creando e rimuovendo le schede in base al contenuto dell'adattatore associato a ViewPager ogni volta che viene chiamato.
Inoltre, imposterà una richiamata in modo che ogni volta che l'utente gira la pagina, verrà selezionata la scheda corrispondente.

Basta definire un layout

<?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>

Quindi implementa FragmentPagerAdapter e applicalo a 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

Fino a poco tempo fa, l'utilizzo di android.support.v4.app.FragmentPagerAdapter avrebbe impedito l'utilizzo di PreferenceFragment come uno dei frammenti utilizzati in FragmentPagerAdapter.

Le ultime versioni della libreria di supporto v7 ora includono la classe PreferenceFragmentCompat , che funzionerà con ViewPager e la versione v4 di FragmentPagerAdapter.

Esempio di frammento che estende 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) { 
 
    } 
}

Ora puoi usare questo frammento in una sottoclasse 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;
        }
    }
    
    // .......

}

Aggiunta di un ViewPager

Assicurati che la seguente dipendenza venga aggiunta al file build.gradle dell'app in dipendenze:

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

Quindi aggiungi ViewPager al tuo layout delle attività:

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

Quindi definisci il tuo 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;
    }    
}

Infine, imposta ViewPager nella tua attività:

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 indicatore di punti

ViewPager con un indicatore di punti

Tutto ciò di cui abbiamo bisogno sono: ViewPager , TabLayout e 2 drawable per punti selezionati e predefiniti.

In primo luogo, dobbiamo aggiungere TabLayout al nostro layout dello schermo e collegarlo a ViewPager . Possiamo farlo in due modi:


TabLayout nidificato in 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>

In questo caso, TabLayout verrà automaticamente collegato a ViewPager , ma TabLayout sarà accanto a ViewPager , non su di lui.


TabLayout separato

<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"/>

In questo caso, possiamo mettere TabLayout ovunque, ma dobbiamo collegare TabLayout con ViewPager a livello di ViewPager

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 volta creato il nostro layout, dobbiamo preparare i nostri punti. Quindi creiamo tre file: selected_dot.xml , default_dot.xml e 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>

Ora abbiamo bisogno di aggiungere solo 3 linee di codice a TabLayout nel nostro layout xml e il gioco è fatto.

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

Imposta OnPageChangeListener

Se è necessario ascoltare le modifiche alla pagina selezionata, è possibile implementare il listener ViewPager.OnPageChangeListener sul 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow