美文网首页安卓自定义控件
自定义控件-字体颜色切换

自定义控件-字体颜色切换

作者: lostmypieces | 来源:发表于2021-06-22 15:50 被阅读0次

    1.分解步骤

    • 1.分析效果
    • 2.确定自定义属性,编写attrs.xml
    • 3.在布局中使用
    • 4.编写自定义控件实现类
    • 5.定义并初始化所需变量(如文字画笔,颜色进度占比等)
    • 5.ondraw()画文字,编写绘制逻辑(主要运用到“切割画板”的思想)
    • 6.其他处理(动画效果)

    2.具体步骤

    • attrs.xml文件 定义需要的控件内部属性变量
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <declare-styleable name="ColorTrackTextView">
        <attr name="originColor" format="color"/>//初始颜色
        <attr name="changeColor" format="color"/>//切换颜色
    </declare-styleable>
    </resources>
    
    • 在layout布局中使用
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="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"
        tools:context=".MainActivity">
    <com.incall.apps.textswitch.ColorTrackTextView
        android:id="@+id/text_draw"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="32sp"
        android:layout_gravity="center"
        app:originColor="@color/black"
        app:changeColor="@color/teal_200"
        android:text="Hello World !!"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="左到右"
            android:layout_gravity="center"
            android:onClick="leftToRight"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="右到右"
            android:layout_gravity="center"
            android:onClick="rightToLeft"/>
    
    </LinearLayout>
    
    • 编写控件类ColorTrackTextView,继承textView
    package com.incall.apps.textswitch;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.widget.TextView;
    
    import androidx.annotation.Nullable;
    @SuppressLint("AppCompatCustomView")
    public class ColorTrackTextView extends TextView {
    
        private Paint mOriginPaint; //初始颜色画笔
        private Paint mChangePaint; //变化颜色画笔
        //设置变色百分比
        private float currentProgress = 0.0f;
        //设置变色朝向
        Direction mdirection = Direction.LEFT_TO_RIGHT;
    
        enum Direction {
            LEFT_TO_RIGHT, RIGHT_TO_LEFT;
        }
    
        public ColorTrackTextView(Context context) {
            this(context, null);
        }
    
        public ColorTrackTextView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public ColorTrackTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            this(context, attrs, defStyleAttr, 0);
        }
    
        public ColorTrackTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            initPaint(context, attrs);
        }
    
        /**
         * 初始化
         */
        private void initPaint(Context context, AttributeSet attrs) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);
            int orginColor = array.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor());
            int changeColor = array.getColor(R.styleable.ColorTrackTextView_changeColor, getTextColors().getDefaultColor());
            mOriginPaint = getPaintByColor(orginColor);
            mChangePaint = getPaintByColor(changeColor);
            array.recycle();
        }
    
        /**
         * 根据颜色值获取画笔
         *
         * @return
         */
        private Paint getPaintByColor(int color) {
            Paint paint = new Paint();
            //设置颜色
            paint.setColor(color);
            //抗锯齿
            paint.setAntiAlias(true);
            //防抖动
            paint.setDither(true);
            //设置字体大小
            paint.setTextSize(getTextSize());
            return paint;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            int middle = (int) (currentProgress * getWidth());
            //从左变到右
            if (mdirection == Direction.LEFT_TO_RIGHT) {
                drawText(canvas, mOriginPaint, middle, getWidth());
                drawText(canvas, mChangePaint, 0, middle);
            }
            //从右边变到左
            else if (mdirection == Direction.RIGHT_TO_LEFT) {
                drawText(canvas, mOriginPaint, 0, getWidth() - middle);
                drawText(canvas, mChangePaint, getWidth() - middle, getWidth());
            }
        }
    
        /**
         * * @description 文字图像绘制
         * @param canvas
         * @param paint
         * @param start
         * @param end
         * @return void
         */
        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;
            //计算基线
            Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
            int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
            int baseLine = getHeight() / 2 + dy;
            canvas.drawText(text, x, baseLine, paint);
            canvas.restore();//释放画板
        }
    
        public void setCurrentProgress(float currentProgress) {
            this.currentProgress = currentProgress;
            invalidate();
        }
    
        public void setMdirection(Direction mdirection) {
            this.mdirection = mdirection;
        }
    }
    
    • 编写MainActivity,添加属性动画,添加按钮逻辑
    package com.incall.apps.textswitch;
    
    import android.animation.ObjectAnimator;
    import android.animation.ValueAnimator;
    import android.os.Bundle;
    import android.view.View;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
        ColorTrackTextView textDraw;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textDraw = findViewById(R.id.text_draw);
        }
    
        public void leftToRight(View view) {
            textDraw.setMdirection(ColorTrackTextView.Direction.LEFT_TO_RIGHT);
            ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 1);
            valueAnimator.setDuration(2000);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float currentProgress = (Float) animation.getAnimatedValue();
                    textDraw.setCurrentProgress(currentProgress);
                }
            });
            valueAnimator.start();
        }
    
        public void rightToLeft(View view) {
            textDraw.setMdirection(ColorTrackTextView.Direction.RIGHT_TO_LEFT);
            ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 1);
            valueAnimator.setDuration(2000);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float currentProgress = (Float) animation.getAnimatedValue();
                    textDraw.setCurrentProgress(currentProgress);
                }
            });
            valueAnimator.start();
        }
    }
    

    3.效果图

    文字颜色转换.gif

    相关文章

      网友评论

        本文标题:自定义控件-字体颜色切换

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