使用網易新聞的時候,如果左右滑動頁面,會發現上面的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);
- }