Android ViewPager 点击或滑动时指示器文字渐变、光标跟随
来源:互联网 发布:论文中英文翻译软件 编辑:程序博客网 时间:2024/06/09 15:06
主要用到的自定义指示器文字类
public class ColorTrackView extends View {private int mTextStartX;private int mTextStartY;public enum Direction {LEFT, RIGHT, TOP, BOTTOM;}private int mDirection = DIRECTION_LEFT;private static final int DIRECTION_LEFT = 0;private static final int DIRECTION_RIGHT = 1;private static final int DIRECTION_TOP = 2;private static final int DIRECTION_BOTTOM = 3;public void setDirection(int direction) {mDirection = direction;}private String mText = "";private Paint mPaint;private int mTextSize = sp2px(30);private int mTextOriginColor = 0xff000000;private int mTextChangeColor = 0xffff0000;private Rect mTextBound = new Rect();private int mTextWidth;private int mTextHeight;private float mProgress;public ColorTrackView(Context context) {super(context, null);}public ColorTrackView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.ColorTrackView);mText = ta.getString(R.styleable.ColorTrackView_text);mTextSize = ta.getDimensionPixelSize(R.styleable.ColorTrackView_text_size, mTextSize);mTextOriginColor = ta.getColor(R.styleable.ColorTrackView_text_origin_color, mTextOriginColor);mTextChangeColor = ta.getColor(R.styleable.ColorTrackView_text_change_color, mTextChangeColor);mProgress = ta.getFloat(R.styleable.ColorTrackView_progress, 0);mDirection = ta.getInt(R.styleable.ColorTrackView_direction, mDirection);ta.recycle();mPaint.setTextSize(mTextSize);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {measureText();int width = measureWidth(widthMeasureSpec);int height = measureHeight(heightMeasureSpec);setMeasuredDimension(width, height);mTextStartX = getMeasuredWidth() / 2 - mTextWidth / 2;mTextStartY = getMeasuredHeight() / 2 - mTextHeight / 2;}private int measureHeight(int measureSpec) {int mode = MeasureSpec.getMode(measureSpec);int val = MeasureSpec.getSize(measureSpec);int result = 0;switch (mode) {case MeasureSpec.EXACTLY:result = val;break;case MeasureSpec.AT_MOST:case MeasureSpec.UNSPECIFIED:result = mTextBound.height();result += getPaddingTop() + getPaddingBottom();break;}result = mode == MeasureSpec.AT_MOST ? Math.min(result, val) : result;return result;}private int measureWidth(int measureSpec) {int mode = MeasureSpec.getMode(measureSpec);int val = MeasureSpec.getSize(measureSpec);int result = 0;switch (mode) {case MeasureSpec.EXACTLY:result = val;break;case MeasureSpec.AT_MOST:case MeasureSpec.UNSPECIFIED:// result = mTextBound.width();result = mTextWidth;result += getPaddingLeft() + getPaddingRight();break;}result = mode == MeasureSpec.AT_MOST ? Math.min(result, val) : result;return result;}private void measureText() {mTextWidth = (int) mPaint.measureText(mText);FontMetrics fm = mPaint.getFontMetrics();mTextHeight = (int) Math.ceil(fm.descent - fm.top);mPaint.getTextBounds(mText, 0, mText.length(), mTextBound);mTextHeight = mTextBound.height();}public void reverseColor() {int tmp = mTextOriginColor;mTextOriginColor = mTextChangeColor;mTextChangeColor = tmp;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int r = (int) (mProgress * mTextWidth + mTextStartX);int t = (int) (mProgress * mTextHeight + mTextStartY);if (mDirection == DIRECTION_LEFT) {drawChangeLeft(canvas, r);drawOriginLeft(canvas, r);} else if (mDirection == DIRECTION_RIGHT) {drawOriginRight(canvas, r);drawChangeRight(canvas, r);} else if (mDirection == DIRECTION_TOP) {drawOriginTop(canvas, t);drawChangeTop(canvas, t);} else {drawOriginBottom(canvas, t);drawChangeBottom(canvas, t);}}private boolean debug = false;private void drawText_h(Canvas canvas, int color, int startX, int endX) {mPaint.setColor(color);if (debug) {mPaint.setStyle(Style.STROKE);canvas.drawRect(startX, 0, endX, getMeasuredHeight(), mPaint);}canvas.save(Canvas.CLIP_SAVE_FLAG);canvas.clipRect(startX, 0, endX, getMeasuredHeight());// left, top,// right, bottomcanvas.drawText(mText, mTextStartX,getMeasuredHeight() / 2- ((mPaint.descent() + mPaint.ascent()) / 2), mPaint);canvas.restore();}private void drawText_v(Canvas canvas, int color, int startY, int endY) {mPaint.setColor(color);if (debug) {mPaint.setStyle(Style.STROKE);canvas.drawRect(0, startY, getMeasuredWidth(), endY, mPaint);}canvas.save(Canvas.CLIP_SAVE_FLAG);canvas.clipRect(0, startY, getMeasuredWidth(), endY);// left, top,canvas.drawText(mText, mTextStartX,getMeasuredHeight() / 2- ((mPaint.descent() + mPaint.ascent()) / 2), mPaint);canvas.restore();}private void drawChangeLeft(Canvas canvas, int r) {drawText_h(canvas, mTextChangeColor, mTextStartX,(int) (mTextStartX + mProgress * mTextWidth));}private void drawOriginLeft(Canvas canvas, int r) {drawText_h(canvas, mTextOriginColor, (int) (mTextStartX + mProgress* mTextWidth), mTextStartX + mTextWidth);}private void drawChangeRight(Canvas canvas, int r) {drawText_h(canvas, mTextChangeColor,(int) (mTextStartX + (1 - mProgress) * mTextWidth), mTextStartX+ mTextWidth);}private void drawOriginRight(Canvas canvas, int r) {drawText_h(canvas, mTextOriginColor, mTextStartX,(int) (mTextStartX + (1 - mProgress) * mTextWidth));}private void drawChangeTop(Canvas canvas, int r) {drawText_v(canvas, mTextChangeColor, mTextStartY,(int) (mTextStartY + mProgress * mTextHeight));}private void drawOriginTop(Canvas canvas, int r) {drawText_v(canvas, mTextOriginColor, (int) (mTextStartY + mProgress* mTextHeight), mTextStartY + mTextHeight);}private void drawChangeBottom(Canvas canvas, int t) {drawText_v(canvas, mTextChangeColor,(int) (mTextStartY + (1 - mProgress) * mTextHeight),mTextStartY + mTextHeight);}private void drawOriginBottom(Canvas canvas, int t) {drawText_v(canvas, mTextOriginColor, mTextStartY,(int) (mTextStartY + (1 - mProgress) * mTextHeight));}public float getProgress() {return mProgress;}public void setProgress(float progress) {this.mProgress = progress;invalidate();}public int getTextSize() {return mTextSize;}public void setTextSize(int mTextSize) {this.mTextSize = mTextSize;mPaint.setTextSize(mTextSize);requestLayout();invalidate();}public void setText(String text) {this.mText = text;requestLayout();invalidate();}public int getTextOriginColor() {return mTextOriginColor;}public void setTextOriginColor(int mTextOriginColor) {this.mTextOriginColor = mTextOriginColor;invalidate();}public int getTextChangeColor() {return mTextChangeColor;}public void setTextChangeColor(int mTextChangeColor) {this.mTextChangeColor = mTextChangeColor;invalidate();}private int dp2px(float dpVal) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpVal, getResources().getDisplayMetrics());}private int sp2px(float dpVal) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,dpVal, getResources().getDisplayMetrics());}private static final String KEY_STATE_PROGRESS = "key_progress";private static final String KEY_DEFAULT_STATE = "key_default_state";@Overrideprotected Parcelable onSaveInstanceState() {Bundle bundle = new Bundle();bundle.putFloat(KEY_STATE_PROGRESS, mProgress);bundle.putParcelable(KEY_DEFAULT_STATE, super.onSaveInstanceState());return bundle;}@Overrideprotected void onRestoreInstanceState(Parcelable state) {if (state instanceof Bundle) {Bundle bundle = (Bundle) state;mProgress = bundle.getFloat(KEY_STATE_PROGRESS);super.onRestoreInstanceState(bundle.getParcelable(KEY_DEFAULT_STATE));return;}super.onRestoreInstanceState(state);}}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xj="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <com.example.view.ColorTrackView android:id="@+id/id_tab_01" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" xj:progress="1" xj:text="一一" xj:text_change_color="#ffff0000" xj:text_origin_color="@color/gray2" xj:text_size="18sp" /> <com.example.view.ColorTrackView android:id="@+id/id_tab_02" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" xj:text="二二" xj:text_change_color="#ffff0000" xj:text_origin_color="@color/gray2" xj:text_size="18sp" /> <com.example.view.ColorTrackView android:id="@+id/id_tab_03" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" xj:text="三三" xj:text_change_color="#ffff0000" xj:text_origin_color="@color/gray2" xj:text_size="18sp" /> <com.example.view.ColorTrackView android:id="@+id/id_tab_04" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" xj:text="四四" xj:text_change_color="#ffff0000" xj:text_origin_color="@color/gray2" xj:text_size="18sp" /> </LinearLayout> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#dddddd" /> <LinearLayout android:layout_width="match_parent" android:layout_height="2dp" > <ImageView android:id="@+id/order_cursor" android:layout_width="wrap_content" android:layout_height="2dp" android:background="@color/red" /> </LinearLayout> <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </android.support.v4.view.ViewPager></LinearLayout>
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {}@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {// 光标跟随移动layoutParams = (LayoutParams) cursor.getLayoutParams();// 获得该控件的布局属性layoutParams.leftMargin = (int) (cursor.getWidth() * (position + positionOffset));cursor.setLayoutParams(layoutParams);// 文字跟随渐变if (positionOffset > 0) {ColorTrackView left = mTabs.get(position);ColorTrackView right = mTabs.get(position + 1);left.setDirection(1);right.setDirection(0);left.setProgress(1 - positionOffset);right.setProgress(positionOffset);}}@Overridepublic void onPageScrollStateChanged(int state) {}});
这样基本就可以实现滑动时文字渐变、光标跟随的效果了
但是接下来遇到了一个问题,如果有4个tab,先点击tab1,再点击tab4,会发现tab1、tab2、tab3文字没有完全变黑,有少许的红色,虽无大碍,但是影响整体美观
查阅资料后,得出是因为viewpager滑动速度引起的,所以修改viewpager的滑动速度就可以了
public class FixedSpeedScroller extends Scroller {private int mDuration = 0;public FixedSpeedScroller(Context context) {super(context);}public FixedSpeedScroller(Context context, Interpolator interpolator) {super(context, interpolator);}@SuppressLint("NewApi")public FixedSpeedScroller(Context context, Interpolator interpolator,boolean flywheel) {super(context, interpolator, flywheel);}@Overridepublic void startScroll(int startX, int startY, int dx, int dy, int duration) {super.startScroll(startX, startY, dx, dy, mDuration);}@Overridepublic void startScroll(int startX, int startY, int dx, int dy) {super.startScroll(startX, startY, dx, dy, mDuration);}public void setmDuration(int time) {mDuration = time;}public int getmDuration() {return mDuration;}}
然后在activity中加入
mScroller = null;mScroller = ViewPager.class.getDeclaredField("mScroller");mScroller.setAccessible(true);scroller = new FixedSpeedScroller(mViewPager.getContext());mScroller.set(mViewPager, scroller);这样的话,点击tab后,viewpager的滑动速度为0,之前所说的问题解决了,但是新的问题来了,滑动viewpager时,又出现滑动结束后文字颜色没有完全变色的问题,所以只需要在onPageScrolled中将Duration恢复就可以了:scroller.setmDuration(1000);
综上所述,所注意的地方就是在点击时将Duration设置为0,滑动时设置为大于0的数,具体数字根据开发实际状况来
欢迎加入QQ群 298029087
附gif一张
下载地址:http://download.csdn.net/detail/qq_18612815/9263665
0 0
- Android ViewPager 点击或滑动时指示器文字渐变、光标跟随
- ViewPager滑动跟随的指示器
- 跟随滑动ViewPager指示器(小圆点跟随滑动效果)
- Android viewpager滑动指示器,滑动卡片,
- android 中 viewpager 滑动的指示器
- android 中 viewpager 滑动的指示器
- android之viewpager进度条跟随页面滑动
- android头部导航跟随viewpager滑动
- android viewPager 滑动标题颜色渐变效果
- Android ViewPager 和PageTransformer滑动颜色渐变
- android viewpager嵌套viewpager点击滑动
- Android 之一个很好的Viewpager滑动指示器
- Android 自定义的颜色滑动转换ViewPager指示器 ColorTransformIndicator
- Android 具有动画的 Viewpager滑动CircleIndicator指示器
- Android 为ViewPager添加滑动指示器(1)
- Android 为ViewPager添加滑动指示器(2)
- Android-自动轮播的ViewPager+滑动指示器
- 高仿今日头条字体渐变指示器,滑动+点击切换,如丝顺滑
- Android之Lru缓存
- 欢迎使用CSDN-markdown编辑器
- 类工厂方法
- CYC-UITableViewCell的动态高度
- Android4.4 平板背光设置
- Android ViewPager 点击或滑动时指示器文字渐变、光标跟随
- Fresco Fbcore源码分析_executor(一)
- Error:(2, 0) Plugin with id 'com.github.dcendents.android-maven' not found.
- MYSQL5.6/5.0管理之主从同步管理 及搭建主从库
- centos7网络连接调试常用命令笔记
- 写android相机应用开发PictureCallback无法执行
- 【挖坑】CERC2012
- 前端开发框架对比
- iOS: JS和Native交互的两种方法,iosjsnative交互