Android ViewPager又探:增加滑动指示条

Android ViewPager再探:增加滑动指示条

上一篇:《Android ViewPager初探:让页面滑动起来》

 

ViewPager只是左右滑动有些丑,也不知道当前位于第几页面。

可以在上方加入滑动指示条,来确定当前位置。

只需要修改activity_main.xml和MainActivity.java即可,Adapter没什么要更改的。

 

首先,在activity_main.xml这个主页面中,修改根布局为LinearLayout,并增加布局TAB:

 1 <LinearLayout
 2         android:id="@+id/ll_tab"
 3         android:layout_width="match_parent"
 4         android:layout_height="45dp"
 5         android:background="#FFFFFF" >
 6 
 7         <TextView
 8             android:id="@+id/tv_first"
 9             android:layout_width="match_parent"
10             android:layout_height="match_parent"
11             android:layout_weight="1"
12             android:gravity="center"
13             android:text="First"
14             android:textSize="20sp" />
15 
16         <TextView
17             android:id="@+id/tv_second"
18             android:layout_width="match_parent"
19             android:layout_height="match_parent"
20             android:layout_weight="1"
21             android:gravity="center"
22             android:text="Second"
23             android:textSize="20sp" />
24 
25         <TextView
26             android:id="@+id/tv_third"
27             android:layout_width="match_parent"
28             android:layout_height="match_parent"
29             android:layout_weight="1"
30             android:gravity="center"
31             android:text="Third"
32             android:textSize="20sp" />
33     </LinearLayout>

 

TAB布局下,应该有滑动指示条。在网上找了个图片命名为slidebar,放在mipmap-hdpi文件夹下,对应的布局为:

1 <ImageView
2         android:id="@+id/cursor"
3         android:layout_width="match_parent"
4         android:layout_height="wrap_content"
5         android:scaleType="matrix"
6         android:src="@mipmap/slidebar"
7         android:contentDescription="slidebar"/>

 

对于cursor这个滑动条指示器,首先定义需要的参数:

1 /*滑动条相关定义*/
2 private ImageView cursor;
3 private int bmp_width = 0;//游标宽度
4 private int offset = 0;//游标图片偏移量
5 private int number = 0;//当前页面编号

 

其次应该初始化它的位置:

 1 //初始化指示器位置
 2     public void initCursorPos() {
 3         // 初始化动画
 4         cursor = (ImageView) findViewById(R.id.cursor);
 5         bmp_width = BitmapFactory.decodeResource(getResources(), R.mipmap.slidebar)
 6                 .getWidth();// 获取图片宽度
 7 
 8         DisplayMetrics dm = new DisplayMetrics();//初始化DisplayMetrics对象
 9         getWindowManager().getDefaultDisplay().getMetrics(dm);//将当前窗口信息放入DisplayMetrics类中
10         int s_width = dm.widthPixels;// 获取分辨率宽度
11         offset = (s_width / viewList.size() - bmp_width) / 2;// 计算偏移量(保证滑动条在该tab下正中间)
12 
13         Matrix matrix = new Matrix();
14         matrix.postTranslate(offset, 0);
15         cursor.setImageMatrix(matrix);// 设置动画初始位置
16     }

Andorid.util 包下的DisplayMetrics 类提供了一种关于显示的通用信息,如显示大小,分辨率和字体。

DisplayMetrics dm = new DisplayMetrics();这句初始化了DisplayMetrics对象,但并未保存信息。

getWindowManager().getDefaultDisplay().getMetrics(dm);这句是获取当前窗口信息,并放入dm中。

偏移量的计算参考了网上例子,让滑动条处于正下方中间。

 

滑动指示条的移动需要跟随viewpager页面改变,这意味着要设置监听:(此处代码参考自:http://blog.csdn.net/harvic880925/article/details/38557517)

 1 //页面改变监听器
 2     public class NewPageChangeListener implements ViewPager.OnPageChangeListener {
 3 
 4         int one = offset * 2 + bmp_width;// 页卡1 -> 页卡2 偏移量
 5         int two = one * 2;// 页卡1 -> 页卡3 偏移量
 6 
 7         @Override
 8         public void onPageSelected(int arg0) {
 9             Animation animation = null;
10             switch (arg0) {
11                 case 0:
12                     if (number == 1) {
13                         animation = new TranslateAnimation(one, 0, 0, 0);
14                     } else if (number == 2) {
15                         animation = new TranslateAnimation(two, 0, 0, 0);
16                     }
17                     break;
18                 case 1:
19                     if (number == 0) {
20                         animation = new TranslateAnimation(offset, one, 0, 0);
21                     } else if (number == 2) {
22                         animation = new TranslateAnimation(two, one, 0, 0);
23                     }
24                     break;
25                 case 2:
26                     if (number == 0) {
27                         animation = new TranslateAnimation(offset, two, 0, 0);
28                     } else if (number == 1) {
29                         animation = new TranslateAnimation(one, two, 0, 0);
30                     }
31                     break;
32             }
33             number = arg0;
34             animation.setFillAfter(true);// True:图片停在动画结束位置
35             animation.setDuration(300);
36             cursor.startAnimation(animation);
37         }
38 
39         @Override
40         public void onPageScrolled(int arg0, float arg1, int arg2) {
41         }
42 
43         @Override
44         public void onPageScrollStateChanged(int arg0) {
45         }
46     }

 

最后,在onCreate()函数内,加上监听操作:

1 viewPager.setCurrentItem(0);//设置当前页
2 viewPager.setOnPageChangeListener(new NewPageChangeListener());//监听页面改变

 

到此,滑动条和viewpager就结合了。

 

如果希望点击tab块,能跳转到相应页面,则需要加上监听操作:

1 /*Tab页面参数*/
2 private TextView tv_first;
3 private TextView tv_second;
4 private TextView tv_third;

onCreate()里:

 1 /*TAB页初始化*/
 2 tv_first = (TextView)findViewById(R.id.tv_first);
 3 tv_second = (TextView)findViewById(R.id.tv_second);
 4 tv_third = (TextView)findViewById(R.id.tv_third);
 5 
 6 
 7 /*Tab页面监听*/
 8 tv_first.setOnClickListener(new TabOnClickListener(0));
 9 tv_second.setOnClickListener(new TabOnClickListener(1));
10 tv_third.setOnClickListener(new TabOnClickListener(2));

对应的监听函数:

 1 /*Tab页面点击监听*/
 2     public class TabOnClickListener implements View.OnClickListener{
 3         private int num = 0;
 4 
 5         public TabOnClickListener(int index){
 6             num = index;
 7         }
 8 
 9         @Override
10         public void onClick(View v){
11             viewPager.setCurrentItem(num);
12         }
13     }

 

 

最后附上MainActivity的完整代码:

Android ViewPager又探:增加滑动指示条Android ViewPager又探:增加滑动指示条
  1 package com.example.viewpager.myapplication;
  2 
  3 import android.app.Activity;
  4 import android.graphics.BitmapFactory;
  5 import android.graphics.Matrix;
  6 import android.os.Bundle;
  7 import android.support.v4.view.ViewPager;
  8 import android.util.DisplayMetrics;
  9 import android.view.LayoutInflater;
 10 import android.view.View;
 11 import android.view.animation.Animation;
 12 import android.view.animation.TranslateAnimation;
 13 import android.widget.ImageView;
 14 import android.widget.TextView;
 15 
 16 import java.util.ArrayList;
 17 import java.util.List;
 18 
 19 
 20 public class MainActivity extends Activity {
 21     private View first,second,third;
 22     private ViewPager viewPager;//对应 <android.support.v4.view.ViewPager/>控件
 23     private List<View> viewList;//View数组
 24 
 25     /*滑动条相关定义*/
 26     private ImageView cursor;
 27     private int bmp_width = 0;//游标宽度
 28     private int offset = 0;//游标图片偏移量
 29     private int number = 0;//当前页面编号
 30 
 31     /*Tab页面参数*/
 32     private TextView tv_first;
 33     private TextView tv_second;
 34     private TextView tv_third;
 35 
 36     @Override
 37     protected void onCreate(Bundle savedInstanceState) {
 38         super.onCreate(savedInstanceState);
 39         setContentView(R.layout.activity_main);
 40 
 41         /*TAB页初始化*/
 42         tv_first = (TextView)findViewById(R.id.tv_first);
 43         tv_second = (TextView)findViewById(R.id.tv_second);
 44         tv_third = (TextView)findViewById(R.id.tv_third);
 45 
 46         /*初始化*/
 47         viewPager = (ViewPager)findViewById(R.id.viewpager);
 48         LayoutInflater inflater = getLayoutInflater();
 49         first = inflater.inflate(R.layout.first_page,null);
 50         second = inflater.inflate(R.layout.second_page,null);
 51         third = inflater.inflate(R.layout.third_page,null);
 52 
 53         viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
 54         viewList.add(first);
 55         viewList.add(second);
 56         viewList.add(third);
 57 
 58         //初始化指示器位置
 59         initCursorPos();
 60 
 61         /*适配器部分*/
 62         NewPagerAdapter pagerAdapter = new NewPagerAdapter(viewList);
 63         viewPager.setAdapter(pagerAdapter);
 64 
 65         viewPager.setCurrentItem(0);//设置当前页
 66         viewPager.setOnPageChangeListener(new NewPageChangeListener());//监听页面改变
 67 
 68         /*Tab页面监听*/
 69         tv_first.setOnClickListener(new TabOnClickListener(0));
 70         tv_second.setOnClickListener(new TabOnClickListener(1));
 71         tv_third.setOnClickListener(new TabOnClickListener(2));
 72     }
 73 
 74     //初始化指示器位置
 75     public void initCursorPos() {
 76         // 初始化动画
 77         cursor = (ImageView) findViewById(R.id.cursor);
 78         bmp_width = BitmapFactory.decodeResource(getResources(), R.mipmap.slidebar)
 79                 .getWidth();// 获取图片宽度
 80 
 81         DisplayMetrics dm = new DisplayMetrics();//初始化DisplayMetrics对象
 82         getWindowManager().getDefaultDisplay().getMetrics(dm);//将当前窗口信息放入DisplayMetrics类中
 83         int s_width = dm.widthPixels;// 获取分辨率宽度
 84         offset = (s_width / viewList.size() - bmp_width) / 2;// 计算偏移量(保证滑动条在该tab下正中间)
 85 
 86         Matrix matrix = new Matrix();
 87         matrix.postTranslate(offset, 0);
 88         cursor.setImageMatrix(matrix);// 设置动画初始位置
 89     }
 90 
 91 
 92     //页面改变监听器
 93     public class NewPageChangeListener implements ViewPager.OnPageChangeListener {
 94 
 95         int one = offset * 2 + bmp_width;// 页卡1 -> 页卡2 偏移量
 96         int two = one * 2;// 页卡1 -> 页卡3 偏移量
 97 
 98         @Override
 99         public void onPageSelected(int arg0) {
100             Animation animation = null;
101             switch (arg0) {
102                 case 0:
103                     if (number == 1) {
104                         animation = new TranslateAnimation(one, 0, 0, 0);
105                     } else if (number == 2) {
106                         animation = new TranslateAnimation(two, 0, 0, 0);
107                     }
108                     break;
109                 case 1:
110                     if (number == 0) {
111                         animation = new TranslateAnimation(offset, one, 0, 0);
112                     } else if (number == 2) {
113                         animation = new TranslateAnimation(two, one, 0, 0);
114                     }
115                     break;
116                 case 2:
117                     if (number == 0) {
118                         animation = new TranslateAnimation(offset, two, 0, 0);
119                     } else if (number == 1) {
120                         animation = new TranslateAnimation(one, two, 0, 0);
121                     }
122                     break;
123             }
124             number = arg0;
125             animation.setFillAfter(true);// True:图片停在动画结束位置
126             animation.setDuration(300);
127             cursor.startAnimation(animation);
128         }
129 
130         @Override
131         public void onPageScrolled(int arg0, float arg1, int arg2) {
132         }
133 
134         @Override
135         public void onPageScrollStateChanged(int arg0) {
136         }
137     }
138 
139 
140     /*Tab页面点击监听*/
141     public class TabOnClickListener implements View.OnClickListener{
142         private int num = 0;
143 
144         public TabOnClickListener(int index){
145             num = index;
146         }
147 
148         @Override
149         public void onClick(View v){
150             viewPager.setCurrentItem(num);
151         }
152     }
153 
154 }
MainActivity.java