美文网首页
Android自定义view-玩转字体变色

Android自定义view-玩转字体变色

作者: 临窗听雨 | 来源:发表于2017-05-28 21:20 被阅读1123次

    一、概述

    继续学习自定义view,主要还是讲解画笔,实现的功能是用两种颜色的画笔画文字,根据滑动的偏移量,实现颜色过渡,可以用于页面的指示器。
    效果图:

    指示器.gif

    二、思路分析

    有两种颜色,一种默认颜色,一种选中的颜色(改变的颜色),一个文本两种不同颜色的画笔去画,画的起始点和结束点(也就是文字的绘制矩形区域)根据左滑或者右滑的偏移量而改变。

    2.1继承自textView自定义默认画笔和改变颜色画笔的颜色属性

     //自定义属性
        public ColorTrackTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ColorTrackTextView);
            mOrignColor = a.getColor(R.styleable.ColorTrackTextView_originColor,mOrignColor);
            mChangeColor = a.getColor(R.styleable.ColorTrackTextView_changeColor,mChangeColor);
            a.recycle();
            mChangePaint = getPaintByColor(mChangeColor);
            mOrignPaint = getPaintByColor(mOrignColor);
        }
    

    2.2在ondraw方法里面绘制

       // 1. 一个文字两种颜色
        // 利用clipRect的API 可以裁剪  左边用一个画笔去画  右边用另一个画笔去画  不断的改变中间值
        @Override
        protected void onDraw(Canvas canvas) {
            // super.onDraw(canvas);
            // canvas.clipRect();  裁剪区域
            // 根据进度把中间值算出来
            int middle = (int) (mCurrentProgress * getWidth());
    
            // 从左变到右
            if(mDirection == Direction.LEFT_TO_RIGHT) {  // 左边是红色右边是黑色
                // 绘制变色
                drawText(canvas, mChangePaint , 0, middle);
                drawText(canvas, mOriginPaint, middle, getWidth());
            }else{
                // 右边是红色左边是黑色
                drawText(canvas, mChangePaint, getWidth()-middle, getWidth());
                // 绘制变色
                drawText(canvas, mOriginPaint, 0, getWidth()-middle);
            }
        }
    

    其中的枚举常量Direction.LEFT_TO_RIGHT,表示颜色从左往右改变,当mCurrentProgress为1时文字完全变为改变的颜色,另外的一种情况就是相反的,颜色从右往左变化,由改变颜色变为默认颜色。
    drawText方法的代码如下:

     /**
         * 绘制Text
         * @param canvas
         * @param paint
         * @param start
         * @param end
         */
        private void drawText(Canvas canvas, Paint paint, int start, int end) {
            canvas.save();
            // 绘制不变色
            Rect rect = new Rect(start, 0, end, getHeight());
            canvas.clipRect(rect);
            String text = getText().toString();
            Rect bounds = new Rect();
            paint.getTextBounds(text, 0, text.length(), bounds);
            // 获取字体的宽度
            int x = getWidth() / 2 - bounds.width() / 2;
            // 基线baseLine
            Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
            int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
            int baseLine = getHeight() / 2 + dy;
            canvas.drawText(text, x, baseLine, paint);// 这么画其实还是只有一种颜色
            canvas.restore();
        }
    

    2.3其他方法:

     public void setDirection(Direction direction){
            this.mDirection = direction;
        }
    
        public void setCurrentProgress(float currentProgress){
            this.mCurrentProgress = currentProgress;
            invalidate();
        }
    
        public void setChangeColor(int changeColor) {
            this.mChangePaint.setColor(changeColor);
        }
    
        public void setOriginColor(int originColor) {
            this.mOriginPaint.setColor(originColor);
        }
    

    暴露给用户去设置默认颜色,和选中颜色。通过调用setCurrentProgress方法,不断的动态传入 方法中不断调用ondraw方法,实现效果。
    看下运行效果图:

    GIF.gif

    2.4集成到viewpager

    比较简单,就不做具体分析,只看下关键代码:

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    Log.e("TAG","position -> "+position +"  positionOffset -> "+positionOffset);
                    // position 代表当前的位置
                    // positionOffset 代表滚动的 0 - 1 百分比
    
                    if (positionOffset > 0) {
                        // 获取左边
                        ColorTrackTextView left = mIndicators.get(position);
                        // 设置朝向
                        left.setDirection(ColorTrackTextView.Direction.DIRECTION_RIGHT);
                       //positionOffset从0变化到1
                        left.setCurrentProgress(1 - positionOffset);
                        try {
                            // 获取右边
                            ColorTrackTextView right = mIndicators.get(position + 1);
                            right.setDirection(ColorTrackTextView.Direction.DIRECTION_LEFT);
                            right.setCurrentProgress(positionOffset);
                        } catch (Exception e) {
    
                        }
                    }
                }
    
                @Override
                public void onPageSelected(int position) {
    
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
            // 默认一进入就选中第一个
            ColorTrackTextView left = mIndicators.get(0);
            left.setDirection(ColorTrackTextView.Direction.DIRECTION_RIGHT);
            left.setCurrentProgress(1);
        }
    

    给viewpager添加监听,在页面滑动的时候调用setCurrentProgress方法绘制文字,头部指示器用LinearLayout添加。代码如下:

      /**
         * 初始化可变色的指示器
         */
        private void initIndicator() {
            for (int i = 0; i < items.length; i++) {
                // 动态添加颜色跟踪的TextView
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT);
                params.weight = 1;
                ColorTrackTextView colorTrackTextView = new ColorTrackTextView(this);
                // 设置颜色
                colorTrackTextView.setTextSize(20);
                colorTrackTextView.setChangeColor(Color.RED);
                colorTrackTextView.setText(items[i]);
                colorTrackTextView.setLayoutParams(params);
                // 把新的加入LinearLayout容器
                mIndicatorContainer.addView(colorTrackTextView);
                // 加入集合
                mIndicators.add(colorTrackTextView);
            }
        }
    

    分析完毕

    三、结语

    参考链接:打造炫酷通用的ViewPager指示器 - Adapter模式适配所有
    代码地址:http://pan.baidu.com/s/1mhRghnE

    相关文章

      网友评论

          本文标题:Android自定义view-玩转字体变色

          本文链接:https://www.haomeiwen.com/subject/ezuhfxtx.html