使用网易新闻的时候,如果左右滑动页面,会发现上面的Tab下面有条红条,可以随着下面页面的滑动而滑动,用来指明当前的页面。研究了一下,发现可以使用ViewPager和自定义View来实现类似的效果。
在使用Viewpager的时候,我们一般都会注册一个OnPageChangeListener,来看一下它的代码:
点击( 此处 )折叠或打开
可以看到这个接口有三个回调的方法,其中onPageScrolled方法在滑动的时候会被调用。这个方法有三个参数,看其说明可以知道 position就是当前显示第一页的序号,positionOffset是一个0到1的数,用来表示当前页滑动的位置,数值越大,就表示滑动的幅度越大。就需要通过这个方法来知道滑动的位置。
下面需要一个自定义的View,来画这个滑动条。当onPageScrolled方法被调用的时候,我们就需要重画来定位滑动条的位置。下面是自定义VIew的代码:
其中LinearGradient是用来设置渐变色的,也可以去掉。最后只需要加上调用更新的代码就可以了:
好了,来看一下实现的效果吧
在使用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);
- }
下面需要一个自定义的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;
- }
- }
点击(此处)折叠或打开
- @Override
- public void onPageScrolled(int position, float positionOffset,
- int positionOffsetPixels) {
- mScllorTabView.setOffset(position, positionOffset);
- }