http://blog.csdn.net/tibib/article/details/8724281高效顯示Bitmap系列的學習、翻譯文章還沒有寫完,估計這個禮拜末能結束吧~
android.support.v4.ViewPager類在 API
4+ Support 支援包中開始為我們提供,它可以讓我們有能力左右滑動以'頁'的形式展示資料。我們可以通過繼承
PagerAdapter 來產生頁面形式的視圖。介紹具體的使用方式之前先來看下效果
首先需要在layout檔案中配置ViewPager View
<android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="50dp" />
其實ViewPager本質上是一個View,繼承體系如下,可以發現它的上面就是ViewGroup ,它是有能力add
View的
| java.lang.Object |
| ↳ |
android.view.View |
| |
↳ |
android.view.ViewGroup |
| |
|
↳ |
android.support.v4.view.ViewPager |
上面提到過使用
PagerAdapter 來產生一個整頁模式,也就是一頁,
PagerAdapter 決定了ViewPager一共有多少頁,負責每頁的初始化,每頁的銷毀等工作
class MyPagerAdapter extends PagerAdapter{ @Override public int getCount() { return mViewList .size(); } @Override public Object instantiateItem(View container, int position) { Log. i("INFO", "instantiate item:"+position); ((ViewPager) container).addView( mViewList.get(position),0); return mViewList .get(position); } @Override public void destroyItem(View container, int position, Object object) { ((ViewPager) container).removeView( mViewList.get(position)); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } }
可以看到ViewPager其實是一個組件容器,可以為它的每頁添加一個要顯示的View,用於展現資料
mLayoutInflater = getLayoutInflater();//可以按照需求進行動態建立Layout,這裡暫用靜態xml layoutmViewList.add(mLayoutInflater.inflate(R.layout.per_pager1, null));mViewList.add(mLayoutInflater.inflate(R.layout.per_pager2, null));mViewList.add(mLayoutInflater.inflate(R.layout.per_pager3, null));ViewPager viewPager = (ViewPager) findViewById(R.id.pager);mPagerAdapter = new MyPagerAdapter();viewPager.setAdapter(mPagerAdapter);
上面的每一個經過inflate的Layout就代表的是每一頁的布局,就像我們平常使用的布局檔案一樣... 我們經常看到一般在ViewPager下會有一些圓點來指示當前我們瀏覽到第幾頁了,要實現這種效果,我們要根據頁面的數量來動態產生圓點的數量,並添加到一個LinearLayout中,便於管理
Bitmap bitmap = BitmapFactory. decodeResource(getResources(), R.drawable.icon_dot_normal ); for (int i = 0; i < mViewList.size(); i++) { Button bt = new Button(this ); bt.setLayoutParams( new ViewGroup.LayoutParams(bitmap.getWidth(),bitmap.getHeight())); bt.setBackgroundResource(R.drawable. icon_dot_normal ); mNumLayout .addView(bt); }
那我們怎麼才能知道當前滑動到第幾頁了呢 ? 其實我們可以為ViewPager設定一個OnPageChangeListener 頁面改變監聽器來監聽頁面的改變,從而得到當前滑動到了第幾頁
viewPager. setOnPageChangeListener( new OnPageChangeListener() { @Override public void onPageSelected( int position) { if (mPreSelectedBt != null){ mPreSelectedBt .setBackgroundResource(R.drawable. icon_dot_normal); } Button currentBt = (Button)mNumLayout .getChildAt(position); currentBt.setBackgroundResource(R.drawable. home_page_dot_select ); mPreSelectedBt = currentBt; //Log.i("INFO", "current item:"+position); } @Override public void onPageScrolled( int arg0, float arg1, int arg2) { // TODO Auto-generated method stub } @Override public void onPageScrollStateChanged( int arg0) { // TODO Auto-generated method stub } });
mPreSelectedBt 只是為了記錄當前顯示的圓點,為下一次圓點焦點切換做準備,下面看一個完整的實現
public class MainActivity extends Activity {ArrayList<View> mViewList = new ArrayList<View>();LayoutInflater mLayoutInflater;LinearLayout mNumLayout;Button mPreSelectedBt;MyPagerAdapter mPagerAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mLayoutInflater = getLayoutInflater();//可以按照需求進行動態建立Layout,這裡暫用靜態xml layoutmViewList.add(mLayoutInflater.inflate(R.layout.per_pager1, null));mViewList.add(mLayoutInflater.inflate(R.layout.per_pager2, null));mViewList.add(mLayoutInflater.inflate(R.layout.per_pager3, null));ViewPager viewPager = (ViewPager) findViewById(R.id.pager);mPagerAdapter = new MyPagerAdapter();viewPager.setAdapter(mPagerAdapter);mNumLayout = (LinearLayout) findViewById(R.id.ll_pager_num);Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_dot_normal);for (int i = 0; i < mViewList.size(); i++) {Button bt = new Button(this);bt.setLayoutParams(new ViewGroup.LayoutParams(bitmap.getWidth(),bitmap.getHeight()));bt.setBackgroundResource(R.drawable.icon_dot_normal);mNumLayout.addView(bt);}viewPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {if(mPreSelectedBt != null){mPreSelectedBt.setBackgroundResource(R.drawable.icon_dot_normal);}Button currentBt = (Button)mNumLayout.getChildAt(position);currentBt.setBackgroundResource(R.drawable.home_page_dot_select);mPreSelectedBt = currentBt;//Log.i("INFO", "current item:"+position);}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub}});}class MyPagerAdapter extends PagerAdapter{@Overridepublic int getCount() {return mViewList.size();}@Overridepublic Object instantiateItem(View container, int position) {Log.i("INFO", "instantiate item:"+position); ((ViewPager) container).addView(mViewList.get(position),0); return mViewList.get(position);}@Overridepublic void destroyItem(View container, int position, Object object) {Log.i("INFO", "destroy item:"+position);((ViewPager) container).removeView(mViewList.get(position)); }@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}}}
如果你仔細觀察列印日誌會發現,PagerAdapter的實現方式有點特殊,永遠都會存在兩個經過初始化的'頁'(page>2時),顯示當前頁時會初始化下一頁,會destroy上上頁,一輪滑動完成的列印資訊如下
04-02 22:39:59.880: I/INFO(27187): instantiate item:004-02 22:39:59.880: I/INFO(27187): instantiate item:104-02 22:40:03.890: I/INFO(27187): instantiate item:204-02 22:40:39.020: I/INFO(27187): destroy item:0
當要顯示的頁數發生改變時,我們可以通過調用PagerAdapter的notifyDataSetChanged() 來通知數據的改變(必須在UI主線程中通知更新),同時圓點也需要進行更新
mViewList.add(mLayoutInflater.inflate(R.layout.per_pager1, null));Button bt = new Button(this);bt.setLayoutParams(new ViewGroup.LayoutParams(bitmap.getWidth(),bitmap.getHeight()));bt.setBackgroundResource(R.drawable.icon_dot_normal);mNumLayout.addView(bt);mPagerAdapter.notifyDataSetChanged();
以上基本上就是ViewPager基本的使用方式,還是比較簡單的,但ViewPager最常使用的方式是結合 Fragment 來一起使用,這種方式可以很方便的來管理每個頁面的生命週期,Android也為我們提供了好些種固定的實現好了的Adapters來給ViewPager使用,它們包括 FragmentPagerAdapter, FragmentStatePagerAdapter,FragmentPagerAdapter,
和 FragmentStatePagerAdapter ,它們中的每一種都可以編寫少量簡單的代碼就為我們建立一個完整的使用者介面,下一節將進行介紹