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、其次,虽然我们在其中使用的是小圆球,但是我们完全可以按照上面的思路,将小圆球改成想微信低栏中的按钮,一切都不在话下

 

posted @ 2014-12-03 17:50  RoperLee  阅读(1266)  评论(0)    收藏  举报