ViewPager筆記

一. 簡介

  1. 官方介紹

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來提供用來顯示的數據(頁面)。

  1. 用法
  • 搭配普通View使用
  • 搭配Fragment使用

二. 三種Adapter

  1. 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)
  1. FragmentPagerAdapter
    2.1 官方介紹
  1. FragmentStatePagerAdapter

三. 使用步驟

  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);
  1. 使用FragmentPagerAdapter的ViewPager
    2.1 xml

四. 注意

  1. 因為ViewPager是在support.v4包里面,因此使用前需要向build.gradle添加
compile 'com.android.support:support-v4:25.2.0'
  1. ViewPager原本自帶兩個子控件PagerTitleStrip和PagerTabStrip,但是MD出來之后這個就不怎么用了,想要了解可參看PagerTitleStripPagerTabStrip

五. 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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容