你的位置:首页 > 操作系统

[操作系统]ViewPager之引导页


一、概述

ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换。

本文介绍ViewPager最基础的应用:在多个View之间进行切换,亦即ViewPager的每个页面是个View。

这种模式适合每个页面的逻辑较为简单的情况,比如去实现“小红书”引导页这样的效果:

 

二、实现思路

2.1 页面如何布局

这个引导页一共有三个页面,毫无疑问上面的标题和配图是隶属于viewpager不同页面内部的,而下面的俩按钮则是直接放在Activity的布局中。

那indicator呢?虽然在不同的页面红点的位置不一样,但它不能放在页面的布局中,否则,三个点就会跟配图一样整体滑动了……

2.2 代码如何实现

ViewPager是什么鬼呢?其实它就是个ViewGroup,用法跟ListView类似,重点在于实现这样一个Adapter:

 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     @Override13     public Object instantiateItem(ViewGroup container, int position) {14       return super.instantiateItem(container, position); //创建一个页面15     }16     17     @Override18     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.1 摆出activity和每个页面的布局

viewpager_view.:

 1 <RelativeLayout ="http://schemas.android.com/apk/res/android" 2   ="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   <Button24     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   <Button36     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.

 1 <RelativeLayout ="http://schemas.android.com/apk/res/android" 2   ="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     @Override100     public void onPageScrollStateChanged(int state) {101     }102   }103 104   @Override105   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] 

四、demo工程

保存下面的图片,扩展名改成 .zip 即可

 [转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html]