Android ViewPager实现页面的切换
【ViewPager】
1、ViewPager需要android-support-v4.jar这个包的支持,如果我们使用这个类的话,需要导入这个包,ViewPager主要用来组织一组数据,并且通过左右滑动的方式来展示
2、步骤要点:
①在布局文件的适当位置,定义一个ViewPager组件
②在Java代码中为这个ViewPager组件指定PagerAdapter,在这个是配种每个元素都是一个View视图
③通过上面的两步我们实际上就已经创建好了一个ViewPager驱动的可滑动的应用了
④我们还能够为这个ViewPager注册一个setOnPageChangeListener(OnPageChangeListener)事件监听器,当ViewPager的当前页面的改变的时候就会回调这个处理器,这样一来我们就能够做很多事儿
3、用途:在很多的应用中都是用这样的界面,比如欢迎页面(也就是已进入App时出来的功能展示页面),微信的主界面,都是能够通过滑动来改变当前视图的
【实例】
还是先来看看效果吧

我用了三张手机截屏图,注意到其中的三个圆点没有,当我们滑动时,这三个圆点的亮暗也发生对应的变化,这非常的简单,因为我们能够为ViewPager注册了监听器,通过监听ViewPager来改变小圆点的亮暗 , 同时当我们点击小球的时候,页面也会对应着动
废话少说,直接上代码:
PagerAdapter适配器文件ScreenPagerAdapter.java 文件:
1 package com.penglee.viewpaper_test; 2 3 import java.util.List; 4 5 import android.os.Parcelable; 6 import android.support.v4.view.PagerAdapter; 7 import android.support.v4.view.ViewPager ; 8 import android.view.View; 9 import android.widget.ImageView; 10 11 public class ScreenPagerAdapter extends PagerAdapter{ 12 13 private List<ImageView> screenViews ; 14 15 public ScreenPagerAdapter(List<ImageView> list){ 16 this.screenViews = list ; 17 } 18 19 //销毁position位置的界面 20 @Override 21 public void destroyItem(View container, int position, Object object) { 22 ((ViewPager) container ).removeView(screenViews.get(position)); 23 } 24 25 @Override 26 public void finishUpdate(View container) { 27 // TODO Auto-generated method stub 28 } 29 30 //获得当前界面数 31 @Override 32 public int getCount() { 33 if (screenViews != null) 34 { 35 return screenViews.size(); 36 } 37 return 0; 38 } 39 40 41 //初始化position位置的界面 42 @Override 43 public Object instantiateItem(View container, int position) { 44 45 ((ViewPager) container ).addView(screenViews.get(position), 0); 46 return screenViews.get(position); 47 } 48 49 //判断是否由对象生成界面 50 @Override 51 public boolean isViewFromObject(View arg0, Object arg1) { 52 return (arg0 == arg1); 53 } 54 55 @Override 56 public void restoreState(Parcelable arg0, ClassLoader arg1) { 57 // TODO Auto-generated method stub 58 59 } 60 61 @Override 62 public Parcelable saveState() { 63 // TODO Auto-generated method stub 64 return null; 65 } 66 67 @Override 68 public void startUpdate(View arg0) { 69 // TODO Auto-generated method stub 70 71 } 72 73 74 }
主布局文件activity_main.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="com.penglee.viewpaper_test.MainActivity" > 6 7 8 <!-- 加载ViewPaper --> 9 <android.support.v4.view.ViewPager 10 android:id="@+id/viewPaper" 11 android:layout_width="match_parent" 12 android:layout_height="match_parent"> 13 14 </android.support.v4.view.ViewPager> 15 16 <!-- 加载三个小圆点 --> 17 <LinearLayout 18 android:id="@+id/linearLayout" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:orientation="horizontal" 22 android:layout_alignParentBottom="true" 23 android:layout_marginBottom="80dp" 24 android:layout_centerHorizontal="true"> 25 26 <ImageView 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:clickable="true" 30 android:padding="15dp" 31 android:layout_gravity="center_vertical" 32 android:src="@drawable/dot"/> 33 <ImageView 34 android:layout_width="wrap_content" 35 android:layout_height="wrap_content" 36 android:clickable="true" 37 android:padding="15dp" 38 android:layout_gravity="center_vertical" 39 android:src="@drawable/dot"/> 40 <ImageView 41 android:layout_width="wrap_content" 42 android:layout_height="wrap_content" 43 android:clickable="true" 44 android:padding="15dp" 45 android:layout_gravity="center_vertical" 46 android:src="@drawable/dot"/> 47 48 </LinearLayout> 49 50 </RelativeLayout>
小球的背景资源dot.xml文件:
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android" > 3 <item android:state_selected="true" android:drawable="@drawable/light" /> 4 <item android:state_selected="false" android:drawable="@drawable/dim" /> 5 6 <!-- 注意:我们在这里一定不能够使用state_enable属性来控制,enable的意思是:能不能响应单击 7 而我们想要的是,圆形点随时都能够响应单击事件 --> 8 </selector>
主Activity MainActivity.java文件:
1 package com.penglee.viewpaper_test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.util.Log; 9 import android.view.View; 10 import android.view.View.OnClickListener; 11 import android.widget.ImageView; 12 import android.widget.Toast; 13 import android.widget.ImageView.ScaleType; 14 import android.widget.LinearLayout; 15 import android.support.v4.view.ViewPager; 16 import android.support.v4.view.ViewPager.OnPageChangeListener; 17 18 19 public class MainActivity extends Activity implements OnClickListener, OnPageChangeListener{ 20 21 private ViewPager viewPager ; 22 private int currentPage = 0; //记录当前处于活动的页面的索引 23 private ImageView [ ] dotViews ; //保存圆点图片 24 //存储ViewPager中要显示的图片的集合 25 int [ ] images = {R.drawable.screen_1 , R.drawable.screen_2 ,R.drawable.screen_3} ; 26 27 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(R.layout.activity_main); 32 33 viewPager = (ViewPager)findViewById(R.id.viewPaper); 34 35 //创建Adapter 36 37 List<ImageView> list = new ArrayList<ImageView>() ; 38 39 LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 40 LinearLayout.LayoutParams.MATCH_PARENT); 41 42 for(int i =0 ; i<images.length ; i ++){ 43 ImageView imageView = new ImageView(MainActivity.this) ; 44 imageView.setLayoutParams(mParams); 45 imageView.setImageResource(images[i]); 46 imageView.setScaleType(ScaleType.FIT_XY); 47 list.add(imageView); 48 } 49 50 ScreenPagerAdapter sPagerAdapter = new ScreenPagerAdapter(list); 51 52 //为ViewPager设置Adapter 53 viewPager.setAdapter(sPagerAdapter); 54 //为ViewPager设置监听器,为的是能够控制圆点的亮暗 55 viewPager.setOnPageChangeListener(MainActivity.this); 56 //对滑动使用动画,这个DepthPageTransformer类是我自己写的一个类,你可以更改它,实现不同的效果,非常的棒 57 viewPager.setPageTransformer(true, new DepthPageTransformer()); 58 59 //对圆点图片进行初始化,控制圆点的亮暗 60 initDot() ; 61 } 62 63 //对圆点图片进行初始化,控制圆点的亮暗 64 public void initDot(){ 65 66 dotViews = new ImageView[ images.length] ; 67 68 LinearLayout ll = (LinearLayout)findViewById(R.id.linearLayout); 69 70 for(int i =0 ; i < dotViews.length ; i++){ 71 dotViews[i] = (ImageView) ll.getChildAt(i); 72 dotViews[i].setSelected(false); //全部设为灰色 73 dotViews[i].setOnClickListener(MainActivity.this); 74 dotViews[i].setTag(i);//为了便于在监听器中进行判别 75 } 76 77 currentPage = 0 ; 78 dotViews[0].setSelected(true); 79 80 } 81 82 /** 83 * 用于设置当前的Screen视图 84 * 85 * */ 86 public void setCurrentPage(int position){ 87 if(position< 0 || position >= images.length){ 88 return ; 89 } 90 viewPager.setCurrentItem(position); 91 } 92 93 /** 94 * 用于设置当前的圆点视图为高亮 95 * 96 * */ 97 public void setCurrentDot(int position){ 98 if(position < 0 || position > images.length - 1 || currentPage == position){ 99 return ; 100 } 101 dotViews[position].setSelected(true); 102 //设置之前的圆点为暗 103 dotViews[currentPage].setSelected(false); 104 105 /*注意不能够使用setEnabled(boolean)方法,首先是要和dot.xml动画文件 对应, 106 其次,是因为enabled属性控制的是:能不能被单击 , 而selected属性才是:当前是否被单击了*/ 107 } 108 109 110 111 //当滑动状态改变时调用 112 @Override 113 public void onPageScrollStateChanged(int arg0) { 114 // TODO Auto-generated method stub 115 116 } 117 118 //当当前页面被滑动时调用 119 @Override 120 public void onPageScrolled(int arg0, float arg1, int arg2) { 121 // TODO Auto-generated method stub 122 123 } 124 125 //当新的页面被选中时调用 126 @Override 127 public void onPageSelected(int arg0) { 128 //将当前的Page对应的小圆点设置为高亮 129 setCurrentDot(arg0); 130 currentPage = arg0; 131 } 132 133 @Override 134 public void onClick(View v) { 135 int position = (Integer)v.getTag(); 136 setCurrentPage(position); 137 setCurrentDot(position); 138 currentPage = position; 139 } 140 }
滑动过程中使用的动画文件DepthPagerAdapterTransformer.java文件:
当然我们完全可以不使用动画,界面也还行,注意这并不是为ViewPager提供动画的唯一方式,有时间可以研究研究动画这方面的知识
1 package com.penglee.viewpaper_test; 2 3 import android.support.v4.view.ViewPager; 4 import android.view.View; 5 6 public class DepthPageTransformer implements ViewPager.PageTransformer 7 { 8 private static final float MIN_SCALE = 0.75f; 9 10 public void transformPage(View view, float position) 11 { 12 int pageWidth = view.getWidth(); 13 14 if (position < -1) 15 { // [-Infinity,-1) 16 // This page is way off-screen to the left. 17 view.setAlpha(0); 18 19 } 20 else if (position <= 0) 21 { // [-1,0] 22 // Use the default slide transition when moving to the left page 23 view.setAlpha(1); 24 view.setTranslationX(0); 25 view.setScaleX(1); 26 view.setScaleY(1); 27 28 } 29 else if (position <= 1) 30 { // (0,1] 31 // Fade the page out. 32 view.setAlpha(1 - position); 33 34 // Counteract the default slide transition 35 view.setTranslationX(pageWidth * -position); 36 37 // Scale the page down (between MIN_SCALE and 1) 38 float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); 39 view.setScaleX(scaleFactor); 40 view.setScaleY(scaleFactor); 41 42 } 43 else 44 { // (1,+Infinity] 45 // This page is way off-screen to the right. 46 view.setAlpha(0); 47 } 48 } 49 }
【文件结构】

【问题】
有时候我们想要实现这样的功能:ViewPager中的每个视图都能够响应点击事件,当我们点击ViewPager中的某张图片的时候,就能够被响应,从而跳转到一个和当前视图对应的另一个界面中,这个怎么实现呢?非常的简单,由于在PagerAdapter中的 public Object instantiateItem( View container , int position) 方法中做的工作是加载position处的view, 那么我们就可以再添加这个view前,为view绑定一个监听器了
1 public class ScreenPagerAdapter extends PagerAdapter{ 2 3 private List<ImageView> screenViews ; 4 Context context ; 5 //因为下面的Toast中要用到一个Context对象,所以必须通过构造方法将MainActivity.this作为参数传过来 6 7 8 public ScreenPagerAdapter(List<ImageView> list , Context context){ 9 this.screenViews = list ; 10 this.context = context ; 11 } 12 13 ......................................................................................... 14 15 ......................................................................................... 16 17 //初始化position位置的界面 18 @Override 19 public Object instantiateItem( View container , int position) { 20 21 final int index = position ; 22 ImageView imageView = screenViews.get(position) ; 23 imageView.setOnClickListener(new OnClickListener(){ 24 25 @Override 26 public void onClick(View v) { 27 Toast.makeText(context,"第"+index +"张图片被点击了", Toast.LENGTH_SHORT).show(); 28 } 29 }); 30 ((ViewPager) container).addView(imageView, 0); 31 return screenViews.get(position); 32 } 33 }
【总结】
1、通过上面的程序,我们很快就能够进行实际项目的开发,List<View>中的View组件可以是任何的自定义组件或者是填充在布局容器中的Fragment组件,这样的话,就可以开发出像样的程序了
2、其次,虽然我们在其中使用的是小圆球,但是我们完全可以按照上面的思路,将小圆球改成想微信低栏中的按钮,一切都不在话下

浙公网安备 33010602011771号