1.实现效果图
效果:滑动的View会随着屏幕滑动而动态滑动
2.滑动条是一个自定义View
实现原理:ViewPager在滑动的过程中,通过对其监听,可以获取滑动的一个幅度,或者说偏移系数,我们可以通过这个偏移系数来计算需要绘制的View的上下左右的一个位置,看代码:
package com.midea.viewpagedemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by xgq on 2016/11/3 0003.
* 使用方法:
* ①.写到XML布局中;
* <com.midea.viewpagedemo.ScrollView
* android:layout_width=“match_parent”
* android:layout_height="自定义高度,单位dp"
* android:id="@+id/scrollView"/>
*
* ②.在Activity中findViewById(int id)获取该控件,
* 在ViewPager滑动监听回调方法onPageScrolled(int position, float offset, int arg2)
* 中调用setOffset(int position, float offset);
*/
public class ScrollView extends View {
/**
* 菜单标签个数
*/
private int mTabNum;
/**
* 第一次进入activity选中的标签角标,基本为第一个,设置0
*/
private int mCurrentNum;
/**
* XML文件中,当前自定义View的宽度,所有标签宽度的总和
*/
private float mWidth;
/**
* 单个菜单标签宽度
*/
private float mTabWidth;
/**
* ViewPager滑动的偏移量,X轴方向偏移的量0~1之间
*/
private float mOffset;
private Paint paint;
public ScrollView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
/**
* 初始化画笔,颜色
* @param color
*/
public void initPaint(int color) {
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(getResources().getColor(color));
}
public void setTabNum(int n) {
mTabNum = n;
}
/**
* 第一次进入Activity需要设置默认滑动条所选中的标签,即定位滑动条
* mOffset设置为移动初始位置,或者说X坐标0的位置
*
* @param n
*/
public void setCurrentNum(int n) {
mCurrentNum = n;
mOffset = 0;
}
/**
* 在ViewPager滑动监听的回调方法中调用
* 滑动时,标签、偏移量都在变动
*
* @param position
* @param offset
*/
public void setOffset(int position, float offset) {
if (offset == 0) {
return;
}
mCurrentNum = position;
mOffset = offset;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mTabWidth == 0) {
mWidth = getWidth();
mTabWidth = mWidth / mTabNum;
}
//通过一个简单的示意图来理解下原理:
//假设当前选中的是第2个标签,则mCurrentNum=1,假设此时偏移量为0.5
//当前有5个标签,分别对应滑动条可能在的5个位置
// 0 1 2 3 4
//------ ------ ------ ------ ------
// 1
// ------ 滚动条滚动到该位置时
//------ --- float left 滚动条在X轴上左边的位置
//------ ------ --- float right 滚动条在X轴上右边的位置
float left = mCurrentNum * mTabWidth + mOffset * mTabWid
// float left = (mCurrentNum + mOffset) * mTabWidth;
final float right = left + mTabWidth;
final float top = getPaddingTop(); //获取标签顶部边界位置
final float bottom = getHeight(); //获取标签底部边界位置
canvas.drawRect(left, top, right, bottom, paint);
}
}
3.把自定义的View添加到XML文件中
android:layout_height=”1dp” 这个即为滑动条的高度。
<com.midea.viewpagedemo.ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="1dp" />
4.在Activity中找到该控件,做相关初始化的设置
直接在Activity的写到onCreate方法中
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
scrollView.setTabNum(5); //设置标签个数
scrollView.setCurrentNum(0); //设置默认选中的标签角标
scrollView.initPaint(R.color.colorAccent);//滑动条颜色
5.ViewPager的滑动监听
通过setOffset方法不断传入偏移系数,达到不断绘制View的一个实现。
public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
/**
* @param arg0 当前显示第一页的序号
* @param arg1 一个0到1的数,用来表示当前页滑动的偏移量,数值越大,
* 则滑动的幅度越大,这个参数用于计算自定义View绘制轨迹。
* @param arg2
*/
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
//页面滑动时的监听,在这里调用自定义View的setOffset方法
scrollView.setOffset(arg0, arg1);
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int arg0) {
setColorAndSize(tvList, arg0);
//页面选中时的监听
}
}