使用网易新闻的时候,如果左右滑动页面,会发现上面的Tab下面有条红条,可以随着下面页面的滑动而滑动,用来指明当前的页面。研究了一下,发现可以使用ViewPager和自定义View来实现类似的效果。
在使用Viewpager的时候,我们一般都会注册一个OnPageChangeListener,来看一下它的代码:
点击(此处)折叠或打开
-
/**
-
* Callback interface for responding to changing state of the selected page.
-
*/
-
public interface OnPageChangeListener {
-
-
/**
-
* This method will be invoked when the current page is scrolled, either as part
-
* of a programmatically initiated smooth scroll or a user initiated touch scroll.
-
*
-
* @param position Position index of the first page currently being displayed.
-
* Page position+1 will be visible if positionOffset is nonzero.
-
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
-
* @param positionOffsetPixels Value in pixels indicating the offset from position.
-
*/
-
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
-
-
/**
-
* This method will be invoked when a new page becomes selected. Animation is not
-
* necessarily complete.
-
*
-
* @param position Position index of the new selected page.
-
*/
-
public void onPageSelected(int position);
-
-
/**
-
* Called when the scroll state changes. Useful for discovering when the user
-
* begins dragging, when the pager is automatically settling to the current page,
-
* or when it is fully stopped/idle.
-
*
-
* @param state The new scroll state.
-
* @see ViewPager#SCROLL_STATE_IDLE
-
* @see ViewPager#SCROLL_STATE_DRAGGING
-
* @see ViewPager#SCROLL_STATE_SETTLING
-
*/
-
public void onPageScrollStateChanged(int state);
-
}
可以看到这个接口有三个回调的方法,其中onPageScrolled方法在滑动的时候会被调用。这个方法有三个参数,看其说明可以知道 position就是当前显示第一页的序号,positionOffset是一个0到1的数,用来表示当前页滑动的位置,数值越大,就表示滑动的幅度越大。就需要通过这个方法来知道滑动的位置。
下面需要一个自定义的View,来画这个滑动条。当onPageScrolled方法被调用的时候,我们就需要重画来定位滑动条的位置。下面是自定义VIew的代码:
-
public class ScllorTabView extends View {
-
-
private int mTabNum, mCurrentNum;
-
private float mWidth, mTabWidth, mOffset;
-
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
private int mBeginColor;
-
private int mEndColor;
-
LinearGradient gradient;
-
-
public ScllorTabView(Context context, AttributeSet attrs) {
-
super(context, attrs);
-
}
-
-
public void setTabNum(int n) {
-
mTabNum = n;
-
}
-
-
public void setCurrentNum(int n) {
-
mCurrentNum = n;
-
mOffset = 0;
-
}
-
-
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;
-
}
-
//根据位置和偏移量来计算滑动条的位置
-
float left = (mCurrentNum + mOffset) * mTabWidth;
-
final float right = left + mTabWidth;
-
final float top = getPaddingTop();
-
final float bottom = getHeight() - getPaddingBottom();
-
-
// if (gradient == null) {
-
LinearGradient gradient = new LinearGradient(left, getHeight(), right,
-
getHeight(), mBeginColor, mEndColor, Shader.TileMode.CLAMP);
-
mPaint.setShader(gradient);
-
// }
-
canvas.drawRect(left, top, right, bottom, mPaint);
-
}
-
-
public void setSelectedColor(int color, int color2) {
-
mBeginColor = color;
-
mEndColor = color2;
-
-
}
-
}
其中LinearGradient是用来设置渐变色的,也可以去掉。最后只需要加上调用更新的代码就可以了:
-
@Override
-
public void onPageScrolled(int position, float positionOffset,
-
int positionOffsetPixels) {
-
mScllorTabView.setOffset(position, positionOffset);
-
}
好了,来看一下实现的效果吧
阅读(14570) | 评论(2) | 转发(1) |