Android
ViewPager
Zoeken…
Invoering
ViewPager is een lay-outmanager waarmee de gebruiker door pagina's met gegevens naar links en rechts kan bladeren. Het wordt meestal gebruikt in combinatie met Fragment, wat een handige manier is om de levenscyclus van elke pagina aan te bieden en te beheren.
Opmerkingen
Een belangrijk ding om op te merken over het gebruik van ViewPager is dat er twee verschillende versies zijn van zowel FragmentPagerAdapter
als FragmentStatePagerAdapter
.
Als u android.app.Fragment
native Fragmenten met een FragmentPagerAdapter of FragmentStatePagerAdapter gebruikt, moet u de v13-ondersteuningsbibliotheekversies van de adapter gebruiken, dat wil zeggen android.support.v13.app.FragmentStatePagerAdapter
.
Als u android.support.v4.app.Fragment
ondersteuningsbibliotheek Fragmenten met een FragmentPagerAdapter of FragmentStatePagerAdapter gebruikt, moet u de v4-ondersteuningsbibliotheekversies van de adapter gebruiken, dat wil zeggen android.support.v4.app.FragmentStatePagerAdapter
.
Basis ViewPager-gebruik met fragmenten
Een ViewPager
maakt het mogelijk om meerdere fragmenten in een activiteit te tonen die kan worden genavigeerd door naar links of rechts te draaien. Een ViewPager
moet worden gevoed door Views of Fragmenten met behulp van een PagerAdapter
.
Er zijn echter twee meer specifieke implementaties die u het handigst vindt in het geval van het gebruik van Fragmenten, namelijk FragmentPagerAdapter
en FragmentStatePagerAdapter
. Wanneer voor de eerste keer een fragment moet worden geïnstantieerd, wordt getItem(position)
aangeroepen voor elke positie die moet worden geïnstantieerd. De methode getCount()
retourneert het totale aantal pagina's, zodat de ViewPager
weet hoeveel fragmenten moeten worden weergegeven.
Zowel FragmentPagerAdapter
als FragmentStatePagerAdapter
houden een cache bij van de fragmenten die de ViewPager
moet tonen. Standaard probeert de ViewPager
maximaal 3 fragmenten op te slaan die overeenkomen met het momenteel zichtbare fragment, en die rechts en links. Ook zal FragmentStatePagerAdapter
de status van elk van uw fragmenten bijhouden.
Houd er rekening mee dat beide implementaties ervan uitgaan dat uw fragmenten hun posities behouden, dus als u een lijst van de fragmenten bijhoudt in plaats van een statisch aantal te hebben zoals u kunt zien in de methode getItem()
, moet u een subklasse van PagerAdapter
en ten minste de methoden instantiateItem()
, destroyItem()
en getItemPosition()
.
Voeg gewoon een ViewPager toe aan uw lay-out zoals beschreven in het basisvoorbeeld :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vpPager">
</android.support.v4.view.ViewPager>
</LinearLayout>
Definieer vervolgens de adapter die bepaalt hoeveel pagina's er zijn en welk fragment moet worden weergegeven voor elke pagina van de adapter.
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;
}
}
}
Als u android.app.Fragment
, moet u deze afhankelijkheid toevoegen:
compile 'com.android.support:support-v13:25.3.1'
Als u android.support.v4.app.Fragment
, moet u deze afhankelijkheid toevoegen:
compile 'com.android.support:support-fragment:25.3.1'
ViewPager met TabLayout
Een TabLayout
kan worden gebruikt voor eenvoudigere navigatie.
U kunt de tabbladen voor elk fragment in uw adapter instellen met behulp van de methode TabLayout.newTab()
, maar er is een andere, gemakkelijkere en gemakkelijkere methode voor deze taak, namelijk TabLayout.setupWithViewPager()
.
Deze methode wordt gesynchroniseerd door tabbladen te maken en te verwijderen op basis van de inhoud van de adapter die aan uw ViewPager
telkens wanneer u deze ViewPager
.
Ook wordt een terugbelopdracht ingesteld, zodat elke keer dat de gebruiker de pagina omdraait, het bijbehorende tabblad wordt geselecteerd.
Definieer gewoon een lay-out
<?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>
Implementeer vervolgens de FragmentPagerAdapter
en pas deze toe op de 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 met PreferenceFragment
Tot voor kort zou het gebruik van android.support.v4.app.FragmentPagerAdapter
het gebruik van een PreferenceFragment
als een van de fragmenten in de FragmentPagerAdapter voorkomen.
De nieuwste versies van de support v7-bibliotheek bevatten nu de klasse PreferenceFragmentCompat
, die werkt met een ViewPager en de v4-versie van FragmentPagerAdapter.
Voorbeeldfragment dat PreferenceFragmentCompat
uitbreidt:
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) {
}
}
U kunt dit fragment nu gebruiken in een android.support.v4.app.FragmentPagerAdapter
subklasse:
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;
}
}
// .......
}
ViewPager toevoegen
Zorg ervoor dat de volgende afhankelijkheid is toegevoegd aan het build.gradle
bestand van uw app onder afhankelijkheden:
compile 'com.android.support:support-core-ui:25.3.0'
Voeg vervolgens de ViewPager
aan uw activiteitenlay-out:
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Definieer vervolgens uw 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;
}
}
ViewPager
ten slotte de ViewPager
in uw activiteit in:
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 met een puntindicator
Alles wat we nodig hebben zijn: ViewPager , TabLayout en 2 drawables voor geselecteerde en standaardpunten.
Ten eerste moeten we TabLayout
toevoegen aan onze schermlay-out en deze verbinden met ViewPager
. We kunnen dit op twee manieren doen:
Geneste tablay-out 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 dit geval wordt
TabLayout
automatisch verbonden metViewPager
, maarTabLayout
zich naastViewPager
, niet boven hem.
Afzonderlijke tab-indeling
<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 dit geval kunnen we zetten
TabLayout
overal, maar we moeten verbindenTabLayout
metViewPager
programmatisch
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);
Nadat we onze lay-out hebben gemaakt, moeten we onze stippen voorbereiden. We maken dus drie bestanden: selected_dot.xml
, default_dot.xml
en 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>
Nu hoeven we slechts 3 coderegels toe te TabLayout
aan TabLayout
in onze XML-lay-out en klaar bent u.
app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
Setup OnPageChangeListener
Als u moet luisteren naar wijzigingen op de geselecteerde pagina, kunt u de ViewPager.OnPageChangeListener
luisteraar in de ViewPager implementeren:
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
}
});