- 參考
ViewPager
Creating Swipe Views with Tabs
Using ViewPager for Screen Slides
ViewPager使用詳解(一):PagerAdapter
一. 簡介
- 官方介紹
Layout manager that allows the user to flip left and right through pages of data. You supply an implementation of a PagerAdapter to generate the pages that the view shows.
ViewPager是一個讓用戶可以向左或者向右滑動來瀏覽視圖的LayoutManager,通過PagerAdapter來提供用來顯示的數據(頁面)。
- 用法
- 搭配普通View使用
- 搭配Fragment使用
二. 三種Adapter
-
PagerAdapter
1.1 官方介紹
Base class providing the adapter to populate pages inside of a ViewPager. You will most likely want to use a more specific implementation of this, such as FragmentPagerAdapter
or FragmentStatePagerAdapter.
ViewPager的基礎適配器,通常建議使用FragmentPagerAdapter和FragmentStatePagerAdapter.
1.2 使用方法
- 新建Class繼承自PagerAdapter,至少實現以下四個方法:
instantiateItem(ViewGroup, int)
destroyItem(ViewGroup, int, Object)
getCount()
isViewFromObject(View, Object)
- 在對應方法里實現想要的邏輯
1.3 Adapter方法介紹
/**
* 獲取View的總數
*
* @return View總數
*/
@Override
public int getCount() {
return 0;
}
/**
* 當ViewPager的內容有所變化時,進行調用。
*
* @param container ViewPager本身
*/
@Override
public void startUpdate(ViewGroup container) {
super.startUpdate(container);
}
/**
* 為給定的位置創(chuàng)建相應的View。創(chuàng)建View之后,需要在該方法中自行添加到container中。
*
* @param container ViewPager本身
* @param position 給定的位置
* @return 提交給ViewPager進行保存的實例對象
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
/**
* 為給定的位置移除相應的View。
*
* @param container ViewPager本身
* @param position 給定的位置
* @param object 在instantiateItem中提交給ViewPager進行保存的實例對象
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
/**
* ViewPager調用該方法來通知PageAdapter當前ViewPager顯示的主要項,提供給用戶對主要項進行操作的方法。
*
* @param container ViewPager本身
* @param position 給定的位置
* @param object 在instantiateItem中提交給ViewPager進行保存的實例對象
*/
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
/**
* 當ViewPager的內容變化結束時,進行調用。當該方法被調用時,必須確定所有的操作已經結束。
*
* @param container ViewPager本身
*/
@Override
public void finishUpdate(ViewGroup container) {
super.finishUpdate(container);
}
/**
* 確認View與實例對象是否相互對應。ViewPager內部用于獲取View對應的ItemInfo。
*
* @param view ViewPager顯示的View內容
* @param object 在instantiateItem中提交給ViewPager進行保存的實例對象
* @return 是否相互對應
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
/**
* 保存與PagerAdapter關聯的任何實例狀態(tài)。
*
* @return PagerAdapter保存狀態(tài)
*/
@Override
public Parcelable saveState() {
return super.saveState();
}
/**
* 恢復與PagerAdapter關聯的任何實例狀態(tài)。
*
* @param state PagerAdapter保存狀態(tài)
* @param loader 用于實例化還原對象的類加載器
*/
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
super.restoreState(state, loader);
}
/**
* 當ViewPager試圖確定某個項的位置是否已更改時調用。默認有兩個可選項:POSITION_UNCHANGED和POSITION_NONE。
* POSITION_UNCHANGED:給定項的位置未變更
* POSITION_NONE:給定項不再用于PagerAdapter中
* 其他值:可以根據具體的情況進行調整
*
* @param object 在instantiateItem中提交給ViewPager進行保存的實例對象
* @return
*/
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
/**
* 新增方法,目前較多用于Design庫中的TabLayout與ViewPager進行綁定時,提供顯示的標題。
*
* @param position 給定的位置
* @return 顯示的標題
*/
@Override
public CharSequence getPageTitle(int position) {
return super.getPageTitle(position);
}
/**
* 獲取給定位置的View的顯示寬度比例,該比例是相對于ViewPager。
*
* @param position 給定的位置
* @return View顯示的寬度比例
*/
@Override
public float getPageWidth(int position) {
return super.getPageWidth(position);
}
1.4 用途:
- 引導頁(不搭配TabLayout)
-
FragmentPagerAdapter
2.1 官方介紹
三. 使用步驟
-
普通ViewPager(使用PagerAdapter的ViewPager)
1.1 xml使用布局
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
android:background="@color/colorPrimary"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager_simple"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
1.2 新建適配器PagerAdapter
/**
* Created by Administrator on 2017/4/14.
*/
public class SimplePagerAdapter extends PagerAdapter {
private Context mContext;
private List<View> mViewList;
private final String TAG = getClass().getSimpleName();
private String[] pagerTitiles = {"Page1","page2"};
public SimplePagerAdapter(Context context, List<View> viewList) {
mContext = context;
mViewList = viewList;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mViewList.get(position));
Log.i(TAG, "instantiateItem: ");
return mViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViewList.get(position));
Log.i(TAG, "destroyItem: ");
}
@Override
public int getCount() {
Log.i(TAG, "getCount: ");
return mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
Log.i(TAG, "isViewFromObject: ");
return view == object;
}
@Override
public CharSequence getPageTitle(int position) {
return pagerTitiles[position];
}
}
1.3 實例化ViewPager,設置適配器
mViewPager = (ViewPager) mRootView.findViewById(R.id.viewpager_simple);
View view1 = inflater.inflate(R.layout.layout_simple_pager1,null);
View view2 = inflater.inflate(R.layout.layout_simple_pager2,null);
List<View> viewList = new ArrayList<>();
viewList.add(view1);
viewList.add(view2);
mSimplePagerAdapter = new SimplePagerAdapter(getContext(),viewList);
mViewPager.setAdapter(mSimplePagerAdapter);
1.4 實例化TabLayout,并setWithViewPager
mTabLayout = (TabLayout) mRootView.findViewById(R.id.tab_layout);
mTabLayout.setupWithViewPager(mViewPager);
-
使用FragmentPagerAdapter的ViewPager
2.1 xml
四. 注意
- 因為ViewPager是在support.v4包里面,因此使用前需要向build.gradle添加
compile 'com.android.support:support-v4:25.2.0'
- ViewPager原本自帶兩個子控件PagerTitleStrip和PagerTabStrip,但是MD出來之后這個就不怎么用了,想要了解可參看PagerTitleStrip和PagerTabStrip
五. TabLayout詳解(點擊進入)
六. ViewPager和Fragment搭配的時候數據動態(tài)刷新的問題
當ViewPager和Fragment搭配使用的時候,當改變fragment數據之后,由于ViewPager機制,若視圖沒有銷毀則數據不會動態(tài)刷新,那么此時我們就需要使用FragmentStatePagerAdapter,該Adapter與FragmentPagerAdapter的區(qū)別就是該Adapter在某個fragment不需要的時候就會立即銷毀其視圖(實測要銷毀還是要重寫getItemPosition方法)。所以,當需要立即更新視圖的時候操作如下:
- 使用FragmentStatePagerAdapter
- 重寫getItemPosition
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
- 刷新數據并notifyDataSetChanged