之前关于如何实现屏幕页面切换,写过一篇《Android中使用ViewFlipper实现屏幕切换》,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpager有自己的adapter,这也让其适应复杂对象,实现数据的动态加载。
ViewPager是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api。而viewpager就是其中之一,利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等。
下面我们就展示下ViewPager可以实现的两种简单效果:
第一种:屏幕的页面的切换(与ViewFlipper的实现效果类似)
实现效果如下(4张视图(layout)):
第一步:在layout布局文件里加入主布局文件viewpager_layout.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical" android:layout_width="match_parent"
4 android:layout_height="match_parent">
5 <android.support.v4.view.ViewPager
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 android:layout_gravity="center"
9 android:gravity="center"
10 android:id="@+id/vp">
11 <android.support.v4.view.PagerTabStrip
12 android:layout_width="match_parent"
13 android:layout_height="wrap_content"
14 android:id="@+id/tap">
15 </android.support.v4.view.PagerTabStrip>
16 </android.support.v4.view.ViewPager>
17 </LinearLayout>
注意事项:
<1、这里ViewPager和PagerTabStrip都要把包名写全了,不然会ClassNotFound
<2、API中说:在布局xml把PagerTabStrip当做ViewPager的一个子标签来用,不能拿出来,不然还是会报错
<3、在PagerTabStrip标签中可以用属性android:layout_gravity=TOP|BOTTOM来指定title的位置
<4、如果要显示出PagerTabStrip某一页的title,需要在ViewPager的adapter中实现getPageTitle(int)
第二步:在layout中建立要展示切换的视图文件(示例中共四个layout1/2/3/4.xml,这里写一个典型):
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 android:orientation="vertical" android:layout_width="match_parent"
5 android:layout_height="match_parent">
6 <ImageView
7 android:layout_width="match_parent"
8 android:layout_height="match_parent"
9 android:src="@mipmap/a1"
10 android:scaleType="centerCrop"
11 android:id="@+id/iv1" />
12 </LinearLayout>
第三步:Java中Activity的实现代码ViewPagerDemo.java(这里未设置pagerTabStrip的属性):
在Activity里实例化ViewPager组件,并设置它的Adapter(就是PagerAdapter,方法与ListView一样的)
实现一个PagerAdapter,覆盖以下方法:
instantiateItem(ViewGroup, int)//用来实例化页卡
destroyItem(ViewGroup, int, Object)//删除页卡
getCount() //返回页卡的数量
isViewFromObject(View, Object)//判断两个对象是否相等
getPageTitle(int position)//设置标签显示的标题
设置指示标签的属性
pagerTabStrip.setTabIndicatorColor();//指示器的颜色
pagerTabStrip.setBackgroundColor();//背影色
pagerTabStrip.setTextColor(Color.WHITE);//字体颜色
1 import android.os.Bundle;
2 import android.support.annotation.Nullable;
3 import android.support.v4.view.PagerAdapter;
4 import android.support.v4.view.ViewPager;
5 import android.support.v7.app.AppCompatActivity;
6 import android.view.View;
7 import android.view.ViewGroup;
8 import java.util.ArrayList;
9 /**
10 * Created by panchengjia on 2016/12/1.
11 */
12 public class ViewPagerDemo extends AppCompatActivity {
13 private ViewPager vp;
14 //声明存储ViewPager下子视图的集合
15 ArrayList<View> views = new ArrayList<>();
16 //显示效果中每个视图的标题
17 String[] titles={"一号美女","二号美女","三号美女","四号美女"};
18 @Override
19 protected void onCreate(@Nullable Bundle savedInstanceState) {
20 super.onCreate(savedInstanceState);
21 setContentView(R.layout.viewpager_layout);
22 vp= (ViewPager) findViewById(R.id.vp);
23 initView();//调用初始化视图方法
24 vp.setAdapter(new MyAdapter());//设置适配器
25 }
26 //初始化视图的方法(通过布局填充器获取用于滑动的视图并存入对应的的集合)
27 private void initView() {
28 View v1 = getLayoutInflater().inflate(R.layout.layout1,null);
29 View v2 = getLayoutInflater().inflate(R.layout.layout2,null);
30 View v3 = getLayoutInflater().inflate(R.layout.layout3,null);
31 View v4 = getLayoutInflater().inflate(R.layout.layout4,null);
32 views.add(v1);
33 views.add(v2);
34 views.add(v3);
35 views.add(v4);
36 }
37 class MyAdapter extends PagerAdapter{
38 @Override
39 public int getCount() {
40 return views.size();
41 }
42 @Override
43 public boolean isViewFromObject(View view, Object object) {
44 return view==object;
45 }
46 //重写销毁滑动视图布局(将子视图移出视图存储集合(ViewGroup))
47 @Override
48 public void destroyItem(ViewGroup container, int position, Object object) {
49 container.removeView(views.get(position));
50 }
51 //重写初始化滑动视图布局(从视图集合中取出对应视图,添加到ViewGroup)
52 @Override
53 public Object instantiateItem(ViewGroup container, int position) {
54 View v =views.get(position);
55 container.addView(v);
56 return v;
57 }
58 @Override
59 public CharSequence getPageTitle(int position) {
60 return titles[position];
61 }
62 }
63 }
第二种:页面轮播效果视图(程序首次启动的引导页实现)
实现效果如下(3张视图滑动引导):
开始代码前注释:1、本次未实现循环轮播效果;2、导航原点资源图片注解:default_holo为未选中状态,touched_holo为选中后实心状态。(也可自己用Shape绘制)
第一步:在layout布局文件里加入主布局文件viewpager_layout.xml
主布局为FrameLayout,在ViewPager(这里因为存在导航原点,不设置PagerTabStrip)上嵌套包含3个导航原点(由滑动视图数量决定)的linearLayout布局(本次设置该布局位于底部):
1 <?xml version="1.0" encoding="utf-8"?>
2 <FrameLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:id="@+id/activity_main"
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 tools:context="com.example.administrator.myapplication11.MainActivity">
9 <android.support.v4.view.ViewPager
10 android:layout_width="match_parent"
11 android:layout_height="match_parent"
12 android:id="@+id/vp">
13 </android.support.v4.view.ViewPager>
14 <LinearLayout
15 android:id="@+id/point_layout"
16 android:layout_width="match_parent"
17 android:layout_height="wrap_content"
18 android:layout_gravity="bottom"
19 android:orientation="horizontal">
20 <ImageView
21 android:layout_width="0dp"
22 android:layout_height="wrap_content"
23 android:layout_weight="1"
24 android:src="@mipmap/default_holo"/>
25 <ImageView
26 android:layout_width="0dp"
27 android:layout_height="wrap_content"
28 android:layout_weight="1"
29 android:src="@mipmap/default_holo" />
30 <ImageView
31 android:layout_width="0dp"
32 android:layout_height="wrap_content"
33 android:layout_weight="1"
34 android:src="@mipmap/default_holo"
35 android:id="@+id/imageView" />
36 </LinearLayout>
37 </FrameLayout>
第二步:Layout中用于滑动切换的视图(示例中共三个layout1/2/3.xml,这里写一个典型)与第一种相同
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical" android:layout_width="match_parent"
4 android:layout_height="match_parent">
5 <ImageView
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 android:scaleType="centerCrop"
9 android:src="@mipmap/genie"/>
10 </LinearLayout>
第三步:Java中Activity的实现代码MainActivity.java
通过实现OnPageChangeListener接口实现在视图切换时导航原点状态的变化),其中关于OnPageChangeListener中方法的详细解释,请参考博文
《ViewPager的setOnPageChangeListener方法详解》这里不做赘述:
1 import android.support.v4.view.PagerAdapter;
2 import android.support.v4.view.ViewPager;
3 import android.support.v7.app.AppCompatActivity;
4 import android.os.Bundle;
5 import android.view.View;
6 import android.view.ViewGroup;
7 import android.widget.ImageView;
8 import android.widget.LinearLayout;
9 import java.util.ArrayList;
10 /**
11 * Created by panchengjia on 2016/11/30.
12 */
13 public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener{
14 private ViewPager vp;
15 private LinearLayout point_layout;
16 ArrayList<View> views =new ArrayList<>();
17 //实例化存储imageView(导航原点)的集合
18 ArrayList<ImageView> imageViews = new ArrayList<>();
19 int currImage;//记录当前页(导航原点)
20 @Override
21 protected void onCreate(Bundle savedInstanceState) {
22 super.onCreate(savedInstanceState);
23 setContentView(R.layout.activity_main);
24 vp= (ViewPager) findViewById(R.id.vp);
25 initView();//调用初始化视图方法
26 initPoint();//调用初始化导航原点的方法
27 vp.addOnPageChangeListener(this);
28 vp.setAdapter(new MyAdapter());
29 }
30 /*将point_layout中包含的imageView(导航原点)添加到imageViewS集合中
31 *并设置layout1(第一视图)的导航原点(对应集合0下标)的图片
32 * 为touched_holo(触摸状态的图片)
33 */
34 private void initPoint() {
35 point_layout= (LinearLayout) findViewById(R.id.point_layout);
36 int counnt = point_layout.getChildCount();//获取point数量
37 for (int i=0;i<counnt;i++){
38 imageViews.add((ImageView) point_layout.getChildAt(i));
39 }
40 imageViews.get(0).setImageResource(R.mipmap.touched_holo);
41 }
42 private void initView() {
43 View v1=getLayoutInflater().inflate(R.layout.layout1,null);
44 View v2=getLayoutInflater().inflate(R.layout.layout2,null);
45 View v3=getLayoutInflater().inflate(R.layout.layout3,null);
46 views.add(v1);
47 views.add(v2);
48 views.add(v3);
49 }
50 //OnPageChangeListener的方法,这里不做具体实现
51 @Override
52 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
53
54 }
55 //设置滑动到对应位置的视图后,导航原点的不同状态(图片)
56 @Override
57 public void onPageSelected(int position) {
58 ImageView preView = imageViews.get(currImage);
59 preView.setImageResource(R.mipmap.default_holo);
60 ImageView currView = imageViews.get(position);
61 currView.setImageResource(R.mipmap.touched_holo);
62 currImage = position;
63 }
64 //OnPageChangeListener的方法,这里不做具体实现
65 @Override
66 public void onPageScrollStateChanged(int state) {
67
68 }
69 class MyAdapter extends PagerAdapter {
70 @Override
71 public int getCount() {
72 return views.size();
73 }
74 @Override
75 public boolean isViewFromObject(View view, Object object) {
76 return view==object;
77 }
78 @Override
79 public void destroyItem(ViewGroup container, int position, Object object) {
80 container.removeView(views.get(position));
81 }
82 @Override
83 public Object instantiateItem(ViewGroup container, int position) {
84 View v = views.get(position);
85 container.addView(v);
86 return v;
87 }
88 }
89 }
至此,本次的ViewPager实现示例所需代码已完成,当然这只是ViewPager最简单的功能,后续还会更新一些ViewPager的高级用法,欢迎小伙伴们继续支持。
当然篇幅所限,这只是ViewPager最最简单的功能
作者: 去吧皮卡丘