Android实习札记(6)---ViewPager使用详解

来源:互联网 发布:淘宝客推广大师手机板 编辑:程序博客网 时间:2024/06/05 15:08

转载自:http://www.2cto.com/kf/201411/353975.html

札记(5)中介绍了Fragment构建简单的底部导航栏,在结尾的时候说要在下一节中,结合Viewpager

实现进入软件时的引导界面,说到ViewPager,很多朋友都用过,不过只知道粘贴复制,连一些基本的

东西都不知道,那是不行的,在本节中就先讲下ViewPager的一些基本概念吧!

 

 

1.首先ViewPager在哪个包下?

\

 

答:如图,就是在v4.view包下,另外,ViewPager也是3.0(api 11)后Google推出的,对于低版本的

可以自行导入v4包来解决低版本兼容的问题!

 

 

2.ViewPager的简单介绍

答:ViewPager就是一个页面切换的组件而已,我们可以往里面填多个view,然后

我们左右滑动切换不同的view而已,和ListView一样,我们也需要一个Adapter(适配器),将要显示

的View和我们的ViewPager进行绑定,而ViewPager有特定的Adapter——PagerAdapter!

另外,Google官方是建议我们使用Fragment来填充ViewPager的,这样可以更加方便的生成

每个Page以及管理每个Page的生命周期!当然也给我们提供了两个不同的Adapter!分别是:

FragmentPageAdapter和FragmentStatePagerAdapter,前者适用于页面较少的情况,后者

适用于页面较多的情况,,对于两个Adapter的区别会在后面进行讲解!

 

\

 

 

3.ViewPager的适配器——PagerAdapter讲解

答:ViewPager和Listview这些组件其实都是类似的,只是前者单位是Page(页面),后者是Item(项)

而PagerAdapter也是特别的!

 

①必须重写的四个方法:

\

 

②方法简介:

先说下简单的两个吧:

getCount( ):获得viewpager中有多少个view

destroyItem( ):移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保

在finishUpdate(viewGroup)返回时视图能够被移除。

而另外两个就涉及到一个key的概念了:

instantiateItem( ):①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来

②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,

当然你也可以自定义自己的key,但是key和每个view要一一对应的关系

isViewFromObject( ):判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是

代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写

return view == object;就可以了,至于为什么要这样讲起来比较复杂,后面有机会进行了解吧

貌似是ViewPager中有个存储view状态信息的ArrayList,根据View取出对应信息的吧!

③代码示例:

Fragment的简单用法:添加三个View到ViewPager,然后滑动

效果图如下:

\

④实现流程:

step 1:定义三个布局,等下用来填充ViewPager的,例子比较简单,直接用不同TextView与背景颜色来区分

view2,view3只需要copy一下,然后改下颜色与文字就可以了

 

view1.xml

 

?
1
2
3
4
<!--?xml version=1.0encoding=utf-8?-->
<linearlayout android:background="#FF6666"android:gravity="center"android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="vertical"xmlns:android="http://schemas.android.com/apk/res/android">   
    <textview android:layout_height="wrap_content"android:layout_width="wrap_content"android:text="第一个Page">
</textview></linearlayout>

 

step 2:主界面布局文件的编写,一个TextView + ViewPager,注意ViewPager的标签:

 

是这样的:android.support.v4.view.ViewPager

 

activity_main.xml:

 

?
1
2
3
4
5
6
7
<linearlayout android:id="@+id/LinearLayout1"android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="vertical"tools:context=".MainActivity"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">
 
    <textview android:background="#FCBC12/"android:gravity="center"android:layout_height="40dp"android:layout_width="match_parent"android:text="简单的ViewPager使用">
     
     
           
</android.support.v4.view.viewpager></textview></linearlayout>

step 3:编写我们的自定义PagerAdapter适配器类,继承PagerAdapter,实现四个基本的方法:

getCount( ),isViewFormObject( ),instantiateItem( ),destoryItem( ),同时还要定义一个View的

集合,用来放viewpager中的view

MyPagerAdapter.java:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
packagecom.jay.example.viewpagerdemo1;
 
importjava.util.ArrayList;
 
importandroid.support.v4.view.PagerAdapter;
importandroid.view.View;
importandroid.view.ViewGroup;
 
publicclass MyPageAdapter extendsPagerAdapter {
 
    privateArrayList<view> viewLists; 
 
    publicMyPageAdapter() {}  
    publicMyPageAdapter(ArrayList<view> viewLists)
    {
        super();
        this.viewLists = viewLists;
    }
     
     
    @Override
    publicint getCount() {    
        returnviewLists.size();
    }
 
    @Override
    publicboolean isViewFromObject(View view, Object object) {
        returnview == object;
    }
     
    @Override
    publicObject instantiateItem(ViewGroup container, intposition) {
        container.addView(viewLists.get(position));
        returnviewLists.get(position);
    }
 
    @Override
    publicvoid destroyItem(ViewGroup container, intposition, Object object) {
        container.removeView(viewLists.get(position));
    }
}
</view></view>

 

step 4:最后就是MainActivity了,也很简单,实例化ViewPager对象以及View集合,然后通过LayoutInflater动态

加载三个view,通过add方法添加到View集合中,接着把View集合作为参数传递给MyPagerAdapter对象,

最后 调用setAdapter(mAdapter);就可以了

MainActivity.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
packagecom.jay.example.viewpagerdemo1;
 
importjava.util.ArrayList;
importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.support.v4.view.ViewPager;
importandroid.view.LayoutInflater;
importandroid.view.View;
 
publicclass MainActivity extendsActivity {
 
    //定义相关变量
    privateView v1,v2,v3;
    privateViewPager vPager;
    privateArrayList<view> aList;
    privateMyPageAdapter mAdapter;
     
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        vPager = (ViewPager) findViewById(R.id.viewpager);
         
        //动态加载三个View
        LayoutInflater li = getLayoutInflater();
        v1 = li.inflate(R.layout.view1, null);
        v2 = li.inflate(R.layout.view2, null);
        v3 = li.inflate(R.layout.view3, null);
        aList = newArrayList<view>();
        aList.add(v1);
        aList.add(v2);
        aList.add(v3);
        mAdapter = newMyPageAdapter(aList);       
        vPager.setAdapter(mAdapter);
     
    }
     
     
}
</view></view>


代码还是比较简单的,自己看看应该能明白的~大笑

 

 

 

4.ViewPager标题栏——PagerTitleStrip与PagerTabStrip

就是跟随着ViewPager滑动而滑动的标题咯,这两个是官方提供的,一个是普通文字,一个是带有下划线,以及可以

点击文字可切换页面,当然官方的肯定是满足不了我们的,不过还是得学习下哈,关于自定义标题等下再讲

 

先看下两个的效果:

height=584height=584

 

 

效果如图所示,

PagerTitleStrip只是一个普通的标题,会跟随Page切换进行切换,

而PagerTabStrip不仅有标题,还有下划线,另外点击标题也可以进行页面的切换,和TabHost有点相似

代码的话3个view就直接复用上面demo1的东西,然后修改一下布局文件和MainActivity就可以了:

 

①PagerTitleStrip的代码:

activity_main.xml:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
<linearlayout android:id="@+id/LinearLayout1"android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="vertical"android:paddingbottom="@dimen/activity_vertical_margin"tools:context=".MainActivity"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">
 
        <textview android:background="#CCFF99"android:gravity="center"android:layout_height="35dp"android:layout_width="match_parent"android:text="PagerTitleStrip效果演示">
     
     
       
           
           
           
    </android.support.v4.view.pagertitlestrip></android.support.v4.view.viewpager>
 
</textview></linearlayout>

MainActivity.java

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
packagecom.jay.example.viewpagerdemo2;
 
importjava.util.ArrayList;
 
importcom.jay.example.viewpagerdemo2.MyPageAdapter;
importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.support.v4.view.ViewPager;
importandroid.view.LayoutInflater;
importandroid.view.View;
 
publicclass MainActivity extendsActivity {
 
        //定义相关变量
        privateView v1,v2,v3;
        privateViewPager vPager;
        privateArrayList<view> aList;
        privateArrayList<string> sList;
        privateMyPageAdapter mAdapter;
         
        @Override
        protectedvoid onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            vPager = (ViewPager) findViewById(R.id.viewpager);
             
             
            LayoutInflater li = getLayoutInflater();
            v1 = li.inflate(R.layout.view1, null);
            v2 = li.inflate(R.layout.view2, null);
            v3 = li.inflate(R.layout.view3, null);
            aList = newArrayList<view>();
            aList.add(v1);
            aList.add(v2);
            aList.add(v3);
            sList = newArrayList<string>();
            sList.add(红色);
            sList.add(蓝色);
            sList.add(黄色);
            mAdapter = newMyPageAdapter(aList,sList);     
            vPager.setAdapter(mAdapter);
         
        }
 
}
</string></view></string></view>


 

②PagerTabStrip的代码:

activity_main.xml:

 

?
1
2
3
4
5
6
7
8
9
10
11
<linearlayout android:id="@+id/LinearLayout1"android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="vertical"android:paddingbottom="@dimen/activity_vertical_margin"tools:context=".MainActivity"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">
 
        <textview android:background="#C0C080"android:gravity="center"android:layout_height="35dp"android:layout_width="match_parent"android:text="PagerTabStrip效果演示">
     
         
           
           
           
    </android.support.v4.view.pagertabstrip></android.support.v4.view.viewpager>
 
</textview></linearlayout>

MainActivity.java

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
packagecom.jay.example.viewpagerdemo3;
 
importjava.util.ArrayList;
 
importcom.jay.example.viewpagerdemo2.R;
importcom.jay.example.viewpagerdemo3.MyPageAdapter;
 
importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.support.v4.view.ViewPager;
importandroid.view.LayoutInflater;
importandroid.view.View;
 
publicclass MainActivity extendsActivity {
 
        //定义相关变量
        privateView v1,v2,v3;
        privateViewPager vPager;
        privateArrayList<view> aList;
        privateArrayList<string> sList;
        privateMyPageAdapter mAdapter;
         
        @Override
        protectedvoid onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            vPager = (ViewPager) findViewById(R.id.viewpager);
             
             
            LayoutInflater li = getLayoutInflater();
            v1 = li.inflate(R.layout.view1, null);
            v2 = li.inflate(R.layout.view2, null);
            v3 = li.inflate(R.layout.view3, null);
            aList = newArrayList<view>();
            aList.add(v1);
            aList.add(v2);
            aList.add(v3);
            sList = newArrayList<string>();
            sList.add(红色);
            sList.add(蓝色);
            sList.add(黄色);
            mAdapter = newMyPageAdapter(aList,sList);     
            vPager.setAdapter(mAdapter);
         
        }
 
}
</string></view></string></view>

 

 

ps:两个的实现代码都是类似的,这里就不多说了,而且这两个东西用的也不多,通常情况下都是按

实际需求自己写一个的,下面给大家演示一个Viewpager实现Tabhost效果的示例吧!

 

 

 

 

5.ViewPager实现TabHost效果:

先来看看效果图咯,正所谓没图你说个XX:

\

 

 

下面就来通过代码来实现上面的效果:

step 1:先完成我们的主界面布局,三个并列的TextView + 作为底部移动条的ImageView+ViewPager

 

activity_main.xml:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<linearlayout android:id="@+id/LinearLayout1"android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="vertical"tools:context=".MainActivity"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">
 
    <linearlayout android:background="#FFFFFF"android:id="@+id/linearLayout1"android:layout_height="60dp"android:layout_width="fill_parent">
 
        <textview android:gravity="center"android:id="@+id/text1"android:layout_height="fill_parent"android:layout_weight="1.0"android:layout_width="fill_parent"android:text="红色">
 
        <textview android:gravity="center"android:id="@+id/text2"android:layout_height="fill_parent"android:layout_weight="1.0"android:layout_width="fill_parent"android:text="蓝色/">
 
        <textview android:gravity="center"android:id="@+id/text3"android:layout_height="fill_parent"android:layout_weight="1.0"android:layout_width="fill_parent"android:text="黄色">
    </textview></textview></textview></linearlayout>
 
    <imageview android:id="@+id/cursor"android:layout_height="wrap_content"android:layout_width="fill_parent"android:scaletype="matrix"android:src="@drawable/a">
 
     
 
</android.support.v4.view.viewpager></imageview></linearlayout>

ps:上面的一些属性可能不理解,那就先放一放,那些是关于动画的,

 

后续会专门对Android中的动画进行一个总结!

 

 

Step 2:自定义一个PageAdapter的适配器,和前面的是一样的

MyPageAdapter.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
packagecom.jay.example.viewpagerdemo4;
 
importjava.util.List;
 
importandroid.support.v4.view.PagerAdapter;
importandroid.support.v4.view.ViewPager;
importandroid.view.View;
 
publicclass MyPagerAdapter extendsPagerAdapter {
 
    publicList<view> mListViews;
 
    publicMyPagerAdapter(List<view> mListViews) {
        this.mListViews = mListViews;
    }
 
    @Override
    publicvoid destroyItem(View arg0, intarg1, Object arg2) {
        ((ViewPager) arg0).removeView(mListViews.get(arg1));
    }
 
    @Override
    publicint getCount() {
        returnmListViews.size();
    }
 
    @Override
    publicObject instantiateItem(View arg0, intarg1) {
        ((ViewPager) arg0).addView(mListViews.get(arg1), 0);
        returnmListViews.get(arg1);
    }
 
    @Override
    publicboolean isViewFromObject(View arg0, Object arg1) {
        returnarg0 == (arg1);
    }
 
}
</view></view>

step 3.创建三个填充到ViewPager中的view,这里直接用前面的就可以了

 

step 4:主Activity的编写,要完成的事有:

1)相关组件的初始化

2)定义TextView点击事件的方法,Pager.setCurrentItem(index);设置当前显示的页面

3)定义一个初始化移动条位置的方法,移动条的起始位置offset = (屏幕宽度/3 - 移动条宽度)/2;

然后通过Matrix的相关方法设置ImageView的位置

4)定义ViewPager页面切换事件,先计算出移动一页与两页的偏移量:

一页 = offset * 2 + 图片宽度

两页 = 一页 * 2

然后根据哪页跳哪页,通过TranslateAnimation设置跳转动画即可

代码如下:

MainActivity.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
packagecom.jay.example.viewpagerdemo4;
 
importjava.util.ArrayList;
importjava.util.List;
importandroid.os.Bundle;
importandroid.support.v4.view.ViewPager;
importandroid.support.v4.view.ViewPager.OnPageChangeListener;
importandroid.util.DisplayMetrics;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.view.animation.Animation;
importandroid.view.animation.TranslateAnimation;
importandroid.widget.ImageView;
importandroid.widget.TextView;
importandroid.app.Activity;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Matrix;
 
 
publicclass MainActivity extendsActivity {
 
    privateViewPager mPager;
    privateList<view> listViews;
    privateImageView cursor;
    privateTextView t1, t2, t3;
    privateint offset = 0;//移动条图片的偏移量
    privateint currIndex = 0;//当前页面的编号
    privateint bmpWidth;// 移动条图片的长度
     
     
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initCursorPos();
        initView();    
    }
     
    //完成View组件的初始化,并将三个view动态地添加到Adapter对象中
    //然后调用setAdapter将view集合与ViewPager绑定,设置进去的页面
    //指向第一个页面setCurrentItem(0),最后设置onclick和onPageChange监听器
    publicvoid initView()
    {
        mPager = (ViewPager) findViewById(R.id.vPager);
        t1 = (TextView) findViewById(R.id.text1);
        t2 = (TextView) findViewById(R.id.text2);
        t3 = (TextView) findViewById(R.id.text3);  
         
        listViews = newArrayList<view>();
        LayoutInflater mInflater = getLayoutInflater();
        listViews.add(mInflater.inflate(R.layout.view1,null));
        listViews.add(mInflater.inflate(R.layout.view2,null));
        listViews.add(mInflater.inflate(R.layout.view3,null));
        mPager.setAdapter(newMyPagerAdapter(listViews));
        mPager.setCurrentItem(0);
         
         
        t1.setOnClickListener(newMyClickListener(0));
        t2.setOnClickListener(newMyClickListener(1));
        t3.setOnClickListener(newMyClickListener(2));
        mPager.setOnPageChangeListener(newMyOnPageChangeListener());
    }
     
    //初始化指示器的位置,就是下面那个移动条一开始放的地方
    publicvoid initCursorPos() {
        cursor = (ImageView) findViewById(R.id.cursor);
        bmpWidth = BitmapFactory.decodeResource(getResources(), R.drawable.a)
                .getWidth();// 获取图片宽度
        DisplayMetrics dm = newDisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        intscreenW = dm.widthPixels;// 获取分辨率宽度
        offset = (screenW / 3- bmpWidth) / 2;// 计算偏移量
        Matrix matrix = newMatrix();
        matrix.postTranslate(offset,0);
        cursor.setImageMatrix(matrix);// 设置动画初始位置
    
     
    //设置点击事件,点击上面文字切换页面的
    publicclass MyClickListener implementsOnClickListener
    {
        privateint index = 0;
        publicMyClickListener(inti)
        {
            index = i;
        }
         
        @Override
        publicvoid onClick(View arg0) {
            mPager.setCurrentItem(index);          
        }
         
    }
     
     
    //监听页面切换时间,主要做的是动画处理,就是移动条的移动
    publicclass MyOnPageChangeListener implementsOnPageChangeListener {
        intone = offset * 2+ bmpWidth;// 移动一页的偏移量,比如1->2,或者2->3
        inttwo = one * 2;// 移动两页的偏移量,比如1直接跳3
 
        @Override
        publicvoid onPageSelected(intindex) {
            Animation animation = null;
            switch(index) {
            case0:
                if(currIndex == 1) {
                    animation = newTranslateAnimation(one, 0,0,0);
                }elseif (currIndex == 2) {
                    animation = newTranslateAnimation(two, 0,0,0);
                }
                break;
            case1:
                if(currIndex == 0) {
                    animation = newTranslateAnimation(offset, one, 0,0);
                }elseif (currIndex == 2) {
                    animation = newTranslateAnimation(two, one, 0,0);
                }
                break;
            case2:
                if(currIndex == 0) {
                    animation = newTranslateAnimation(offset, two, 0,0);
                }elseif (currIndex == 1) {
                    animation = newTranslateAnimation(one, two, 0,0);
                }
                break;
            }
            currIndex = index;
            animation.setFillAfter(true);// true表示图片停在动画结束位置
            animation.setDuration(300);//设置动画时间为300毫秒
            cursor.startAnimation(animation);//开始动画
        }
 
        @Override
        publicvoid onPageScrollStateChanged(intarg0) {}
 
        @Override
        publicvoid onPageScrolled(intarg0, floatarg1, intarg2) {}
     
    }
}
</view></view>