ViewPager簡介
ViewPager是一個允許使用者左右滑動數據頁面的布局管理器,通過一個適配器(PagerAdapter)來管理要顯示的頁面。 ViewPager更多的時候會與Fragment一起使用,這是一種很好的方法來管理各個頁面的生命周期。Android提供了一些專門的適配器來讓ViewPager與Fragment一起工作,也就是FragmentPagerAdapter與FragmentStatePagerAdapter。
1、ViewPager主要用來實現左右滑動數據頁面的功能;
2、ViewPager使用適配器來連接“視圖”和“數據”;
3、官方推薦ViewPager與Fragment一起使用,并且提供專門的適配器。
PagerAdapter簡介
PagerAdapter是用于“將多個頁面填充到ViewPager”的適配器的一個基類,自定義Adapter時需要繼承它。但大多數情況下更傾向于使用一個實現了PagerAdapter并且更加具體的適配器,例如FragmentPagerAdapter或者FragmentStatePagerAdapter。
自定義Adapter繼承PagerAdapter必須實現以下4個方法:
1、instantiateItem()負責初始化指定位置的頁面,并且需要返回當前頁面(其實是能唯一標識該頁面的key,不過暫時先用View本身作為key);
2、destroyItem()負責移除指定位置的頁面;
3、isViewFromObject()里先暫時直接寫return view == object;
(如果在instantiateItem()里返回的不是View本身而是Key,那就不能這么寫了);
4、getCount()就是返回要展示的頁面的數量。
具體實現:
這里打算將自定義的View填充到ViewPager中,暫時不與Fragment一起使用。
自定義4個View分別是Page1、Page2、Page3、Page4,布局如下:
page1.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:text="Page1"
android:textSize="30sp"/>
</RelativeLayout>
布局中只是添加一個TextView顯示文字而已,這里只展示Page1,其它3個類似。
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jun.viewpagertest.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/mViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private LayoutInflater layoutInflater;
private View page1,page2,page3,page4;
private List<View> pageList;
private ViewPager mViewPager;
private MyPagerAdapter myPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//準備數據
layoutInflater=getLayoutInflater();
page1 = layoutInflater.inflate(R.layout.page1, null);
page2 = layoutInflater.inflate(R.layout.page2, null);
page3 = layoutInflater.inflate(R.layout.page3, null);
page4 = layoutInflater.inflate(R.layout.page4, null);
pageList = new ArrayList<View>();
pageList.add(page1);
pageList.add(page2);
pageList.add(page3);
pageList.add(page4);
//獲取ViewPager
mViewPager = (ViewPager) findViewById(R.id.mViewPager);
//將數據與ViewPager通過Adapter適配在一起
myPagerAdapter = new MyPagerAdapter(pageList);
mViewPager.setAdapter(myPagerAdapter);
}
}
MyPagerAdapter.java
public class MyPagerAdapter extends PagerAdapter {
private List<View> pageList;
public MyPagerAdapter(List<View> pageList) {
this.pageList = pageList;
}
//Page的數目
@Override
public int getCount() {
return pageList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
//在銷毀Item的同時刪除Page的視圖
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(pageList.get(position));
}
//在初始化Item的同時添加Page的視圖
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(pageList.get(position));
return pageList.get(position);
}
}
FragmentPagerAdapter
FragmentPagerAdapter繼承自PagerAdapter ,主要用來展示多個Fragment頁面,并且每一個Fragment都會被保存在FragmentManager中。 FragmentPagerAdapter最適用于那種少量且相對靜態的頁面。對于較多的頁面集合,更推薦使用FragmentStatePagerAdapter。 FragmentPagerAdapter的派生類只需要實現getItem()和getCount()即可。
FragmentStatePagerAdapter
FragmentStatePagerAdapter繼承自PagerAdapter,主要使用Fragment來管理每個頁面。這個類同樣用來保存和恢復Fragment頁面的狀態。 FragmentStatePagerAdapter更多用于大量頁面,例如視圖列表。當某個頁面對用戶不再可見時,他們的整個Fragment就會被銷毀,僅保留Fragment狀態。相比于FragmentPagerAdapter,這樣做的好處是在訪問各個頁面時能節約大量的內存開銷,但代價是在頁面切換時會增加非常多的開銷。 當使用FragmentStatePagerAdapter的時候對應的ViewPager必須擁有一個有效的ID集。 FragmentStatePagerAdapter的派生類也只需要實現getItem()和getCount()即可。
注意:如果要使用FragmentPagerAdapter或FragmentStatePagerAdapter的話,自定義Activity必須繼承FragmentActivity。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:text="Page1"
android:textSize="30sp"/>
</RelativeLayout>
這里只展示一個其它類似。
Fragment1.java
public class Fragment1 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.page1, null);
}
}
這里也只展示一個其它類似。
MyFragmentAdapter.java
public class MyFragmentAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
//需要同時獲取FragmentManager和數據
public MyFragmentAdapter(FragmentManager fm,
List<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
//獲取Item的數據,也就是Fragment
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
//ViewPager的Item數目
@Override
public int getCount() {
return fragmentList.size();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<Fragment> fragmentList;
private ViewPager mViewPager;
private MyFragmentAdapter myFragmentAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//準備數據
Fragment1 mFragment1 = new Fragment1();
Fragment2 mFragment2 = new Fragment2();
Fragment3 mFragment3 = new Fragment3();
Fragment4 mFragment4 = new Fragment4();
fragmentList = new ArrayList<Fragment>();
fragmentList.add(mFragment1);
fragmentList.add(mFragment2);
fragmentList.add(mFragment3);
fragmentList.add(mFragment4);
//獲取ViewPager
mViewPager = (ViewPager) findViewById(R.id.mViewPager);
//將數據與ViewPager通過適配器連接在一起
myFragmentAdapter = new MyFragmentAdapter(
getSupportFragmentManager(),
fragmentList);
mViewPager.setAdapter(myFragmentAdapter);
}
}