1、概述html
ViewPager是android-support-v4中提供的類,它是一個容器類,經常使用於頁面之間的切換。android
本文介紹ViewPager最基礎的應用:在多個View之間進行切換,亦即ViewPager的每一個頁面是個View。緩存
這種模式適合每一個頁面的邏輯較爲簡單的狀況,好比去實現「小紅書」引導頁這樣的效果:app
2、實現思路ide
2.1 頁面如何佈局佈局
這個引導頁一共有三個頁面,毫無疑問上面的標題和配圖是隸屬於viewpager不一樣頁面內部的,而下面的倆按鈕則是直接放在Activity的佈局中。性能
那indicator呢?雖然在不一樣的頁面紅點的位置不同,但它不能放在頁面的佈局中,不然,三個點就會跟配圖同樣總體滑動了……this
2.2 代碼如何實現spa
ViewPager是什麼鬼呢?其實它就是個ViewGroup,用法跟ListView相似,重點在於實現這樣一個Adapter:code
1 private class ViewPagerAdapter extends PagerAdapter { 2 @Override 3 public int getCount() { 4 return 0; //ViewPager總共有幾個頁面 5 } 6 7 @Override 8 public boolean isViewFromObject(View view, Object object) { 9 return false; //判斷一個頁面(View)是否與instantiateItem方法返回的Object一致 10 } 11 12 @Override 13 public Object instantiateItem(ViewGroup container, int position) { 14 return super.instantiateItem(container, position); //建立一個頁面 15 } 16 17 @Override 18 public void destroyItem(ViewGroup container, int position, Object object) { 19 super.destroyItem(container, position, object); //銷燬一個頁面 20 } 21 }
[轉載請保留本文地址:http://www.cnblogs.com/snser/p/5700751.html]
3、開始幹活
3.1 擺出activity和每一個頁面的佈局
viewpager_view.xml (activity的佈局):
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@drawable/viewpager_view_bg" 6 tools:context="${relativePackage}.${activityClass}" > 7 8 <android.support.v4.view.ViewPager 9 android:id="@+id/viewpager_view_pager" 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" 12 android:background="@drawable/viewpager_view_bg" /> 13 14 <ImageView 15 android:id="@+id/viewpager_view_point" 16 android:layout_width="66.7dp" 17 android:layout_height="10dp" 18 android:layout_centerHorizontal="true" 19 android:layout_above="@+id/viewpager_view_register" 20 android:layout_marginBottom="20dp" 21 android:src="@drawable/viewpager_view_point_1" /> 22 23 <Button 24 android:id="@+id/viewpager_view_register" 25 android:layout_width="190dp" 26 android:layout_height="45dp" 27 android:layout_centerHorizontal="true" 28 android:layout_above="@+id/viewpager_view_login" 29 android:layout_marginBottom="10dp" 30 android:background="@drawable/viewpager_view_register_bg" 31 android:textSize="19sp" 32 android:textColor="#FFFFFF" 33 android:text="@string/viewpager_view_register" /> 34 35 <Button 36 android:id="@+id/viewpager_view_login" 37 android:layout_width="190dp" 38 android:layout_height="45dp" 39 android:layout_alignParentBottom="true" 40 android:layout_centerHorizontal="true" 41 android:layout_marginBottom="50dp" 42 android:background="@drawable/viewpager_view_login_bg" 43 android:textSize="19sp" 44 android:textColor="#999999" 45 android:text="@string/viewpager_view_login" /> 46 47 </RelativeLayout>
viewpager_view_page.xml (頁面的佈局):
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context="${relativePackage}.${activityClass}" > 6 7 <TextView 8 android:id="@+id/viewpager_view_page_title" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_marginTop="30dp" 12 android:layout_centerHorizontal="true" 13 android:textSize="20sp" 14 android:textColor="#333333" 15 android:text="@string/viewpager_view_page_title_1" /> 16 17 <ImageView 18 android:id="@+id/viewpager_view_page_content" 19 android:visibility="visible" 20 android:layout_width="match_parent" 21 android:layout_height="385dp" 22 android:layout_marginTop="75dp" 23 android:layout_gravity="center_horizontal" 24 android:scaleType="centerInside" 25 android:src="@drawable/viewpager_view_page_content_1" /> 26 27 </RelativeLayout>
3.2 簡要介紹一下即將出爐的核心代碼
1 public class ViewPagerViewActivity extends Activity implements View.OnClickListener { 2 3 private ViewPager mPager; 4 private ImageView mImgPoint; 5 6 private SparseArray<View> mPageCache = new SparseArray<View>(); 7 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.viewpager_view); 12 initView(); 13 } 14 15 private void initView() { 16 mPager = (ViewPager)findViewById(R.id.viewpager_view_pager); 17 mImgPoint = (ImageView)findViewById(R.id.viewpager_view_point); 18 mPager.setAdapter(new ViewPagerAdapter(ViewPagerViewActivity.this)); 19 mPager.addOnPageChangeListener(new OnViewPageChangeListener()); 20 findViewById(R.id.viewpager_view_register).setOnClickListener(this); 21 findViewById(R.id.viewpager_view_login).setOnClickListener(this); 22 } 23 24 private class ViewPagerAdapter extends PagerAdapter { 25 private final int mCount = 3; 26 private LayoutInflater mInflater; 27 28 private ViewPagerAdapter(Context context) { 29 mInflater = LayoutInflater.from(context); 30 } 31 32 @Override 33 public int getCount() { 34 return mCount; 35 } 36 37 @Override 38 public boolean isViewFromObject(View view, Object obj) { 39 return view == obj; 40 } 41 42 @Override 43 public Object instantiateItem(ViewGroup container, int position) { 44 View page = mPageCache.get(position); 45 if (page == null) { 46 page = mInflater.inflate(R.layout.viewpager_view_page, container, false); 47 TextView txtTitle = (TextView)page.findViewById(R.id.viewpager_view_page_title); 48 ImageView imgContent = (ImageView)page.findViewById(R.id.viewpager_view_page_content); 49 switch (position) { 50 case 0: 51 txtTitle.setText(R.string.viewpager_view_page_title_1); 52 imgContent.setImageResource(R.drawable.viewpager_view_page_content_1); 53 break; 54 case 1: 55 txtTitle.setText(R.string.viewpager_view_page_title_2); 56 imgContent.setImageResource(R.drawable.viewpager_view_page_content_2); 57 break; 58 case 2: 59 txtTitle.setText(R.string.viewpager_view_page_title_3); 60 imgContent.setImageResource(R.drawable.viewpager_view_page_content_3); 61 break; 62 default: 63 break; 64 } 65 mPageCache.append(position, page); 66 } 67 container.addView(page); 68 return page; 69 } 70 71 @Override 72 public void destroyItem(ViewGroup container, int position, Object object) { 73 container.removeView((View)object); 74 } 75 } 76 77 private class OnViewPageChangeListener implements OnPageChangeListener { 78 @Override 79 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 80 } 81 82 @Override 83 public void onPageSelected(int position) { 84 switch (position) { 85 case 0: 86 mImgPoint.setImageResource(R.drawable.viewpager_view_point_1); 87 break; 88 case 1: 89 mImgPoint.setImageResource(R.drawable.viewpager_view_point_2); 90 break; 91 case 2: 92 mImgPoint.setImageResource(R.drawable.viewpager_view_point_3); 93 break; 94 default: 95 break; 96 } 97 } 98 99 @Override 100 public void onPageScrollStateChanged(int state) { 101 } 102 } 103 104 @Override 105 public void onClick(View v) { 106 finish(); 107 } 108 }
重點關注下 ViewPagerAdapter :
在 instantiateItem 方法中會inflate出新的頁面,再根據不一樣的position對頁面進行對應的初始化工做,同時在ViewPager中添加當前頁面。
而在 destroyItem 方法中,只須要將當前頁面從ViewPager中移除便可。
同時,須要給ViewPager設置一個 OnPageChangeListener ,以便在頁面切換的時候更新Indicator對應的小紅點位置。
3.3 關於緩存
能夠看到,上面的代碼在 instantiateItem 方法中用到了頁面緩存,亦即每一個position對應的頁面只須要inflate一次。
那爲何會有緩存的需求呢?這是由於ViewPager每次加載當前頁面的同時,會自動預加載(instantiateItem)與當前頁面左右相隔的兩個頁面,同時會銷燬(destroyItem)與當前頁面不相鄰的頁面。
設想一下,滑動到第三個頁面時,第一個頁面會被銷燬掉,而滑回第二個頁面時,又會從新建立第一個頁面。若是不加以緩存,就會形成頁面的重複inflate從而浪費資源、下降性能。
[轉載請保留本文地址:http://www.cnblogs.com/snser/p/5700751.html]
4、demo工程
保存下面的圖片,擴展名改爲 .zip 便可
[轉載請保留本文地址:http://www.cnblogs.com/snser/p/5700751.html]