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的完整代码:
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 }