自定义view - 玩转字体变色

自定义View步骤:
1>:values__attrs.xml,定义自定义属性;
2>:在第三个构造方法中获取自定义属性;
3>:onMeasure【不是必须的】;
4>:onDraw:绘制代码全都在onDraw中写的;
这篇文章主要是结合属性动画自定义一个文字变色的view。先来看效果图。
在这里插入图片描述技术分析:
不能用TextView,因为系统的TextView只能有一种颜色,需要ColorTraceTextView,继承TextView,而不是继承View,原因是:
1>:继承TextView不用自己手动实现onMeasure、onDraw,系统已经实现了;
2>:textColor、textSize属性TextView已经实现了,不用自己实现;
3>: 自定义属性a.不变的颜色 origincolor b.变化的颜色 changcolor

1.字体颜色

自定义属性:attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ColorTrackText">
        <attr name="originColor" format="color"/>
        <attr name="changeColor" format="color"/>
    </declare-styleable>
</resources>

使用属性:avtivity_main.xml

<?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:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.view_day04.ColorTrackTextView
        android:id="@+id/ColorTrackTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello world"
        android:textSize="20sp"
        app:changeColor ="@color/purple_200"
        app:originColor = "@color/black"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="左到右"
        android:onClick="leftToRight"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="右到左"
        android:onClick="rightToLeft"/>

</LinearLayout>

2.自定义View–初始化、获取画笔、绘制、实现不同朝向

ColorTrackTextView.java

2.1.初始化、画笔、 绘制

public class ColorTrackTextView extends TextView{

    // 绘制不变色的画笔
    private Paint mOriginPaint ;
    // 绘制变色的画笔
    private Paint mChangePaint ;
    private float mCurrentProgress = 0.0f;
    private Direction mDirection;
    //实现不同朝向
    public enum Direction {
        LEFT_TO_RIGHT,RIGHT_TO_LEFT
    }
    public ColorTrackTextView(Context context) {
        this(context, null);
    }

    public ColorTrackTextView(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorTrackTextView(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint(context, attrs);
    }

    private void initPaint(Context context, AttributeSet attrs)
    {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackText);
        // 此处颜色传递默认值,防止你在布局文件中没有指定颜色
        int originColor = typedArray.getColor(R.styleable.ColorTrackText_originColor, getTextColors().getDefaultColor());
        int changeColor = typedArray.getColor(R.styleable.ColorTrackText_changeColor, getTextColors().getDefaultColor());
        mOriginPaint = getPaintByColor(originColor);
        mChangePaint = getPaintByColor(changeColor);
        typedArray.recycle();
    }

    private Paint getPaintByColor(int color) {
        Paint paint = new Paint() ;
        // 给画笔设置颜色
        paint.setColor(color);
        // 设置抗锯齿
        paint.setAntiAlias(true);
        // 仿抖动
        paint.setDither(true);
        // 设置文字大小,拿到布局中的Textsize
        paint.setTextSize(getTextSize());
        return paint;
    }

    //利用cliprect可以裁剪,左边用一个画笔去画,右边用另一个画笔去画 不断地改变中间值
    @Override
    protected void onDraw(Canvas canvas) {

        //根据进度把中间值是算出来
        int middle = (int)(mCurrentProgress * getWidth());
        if (mDirection == Direction.LEFT_TO_RIGHT) {
            //绘制不变色的
            drawText(canvas,mOriginPaint,0, middle);
            //绘制变色的
            drawText(canvas,mChangePaint,middle, getWidth());
        } else {
            // 右-左:
            drawText(canvas , mChangePaint , getWidth()-middle , getWidth());
            drawText(canvas , mOriginPaint , 0 , getWidth()-middle);
        }
    }

    /**
     * 画文字
     */
    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 setDirection(Direction direction){
        this.mDirection = direction;
    }

    /**
     * 设置当前进度
     */
    public void setCurrentProgress(float currentProgress){
        this.mCurrentProgress = currentProgress;
        // 获取到当前进度后,进行重绘
        invalidate();
    }

    /**
     * 设置改变的颜色
     */
    public void setChangeColor(int color){
        this.mChangePaint.setColor(color);
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/51253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

emacs打开git仓库下多个子工程的根目录问题解决案

emacs打开git仓库下多个子工程的根目录问题解决案 问题描述 如题所述&#xff0c;这个问题困扰我很久了&#xff0c;一直没搜到完整的解决方案。这次终于乘着空闲时间&#xff0c;研究了projectile.el源码找到了方案。 问题场景具体描述下: 我自己有一个私人git仓库&#x…

机器学习:GPT3

GPT3 模型过于巨大 GPT3是T5参数量的10倍&#xff01; 训练GPT3的代价是$12百万美元 Zero-shot Ability GPT3的思想是不是能拿掉Fine-tune 只需要给定few-shot或者zero-shot就能干相应的任务了。 few-shot learning&#xff08;no gradient descent&#xff09;&#…

(学习笔记)matplotlib.pyplot模块下基本画图函数的整理

matplotlib版本&#xff1a;3.7.1 python版本&#xff1a;3.10.12 基本函数 matplotlib版本&#xff1a;3.7.1python版本&#xff1a;3.10.12 1. plt.plot()函数1.1 plt.plot(x, y)1.2 plt.plot(x, y, **kwargs) 2. plt.xlable(), plt.ylable()3. plt.title()4. plt.show()5.p…

SkyWalking链路追踪-技术文档首页

SkyWalking 文档中文版&#xff08;社区提供&#xff09; (skyapm.github.io)https://skyapm.github.io/document-cn-translation-of-skywalking/ SkyWalking-基本概念 SkyWalking链路追踪是一个用于分布式系统的性能监控工具&#xff0c;它帮助开发人员了解系统中各组件之间…

向量vector模板输出、倒置、求和

运行代码&#xff1a; //向量vector模板输出、倒置、求和 #include"std_lib_facilities.h" //定义vector<double>的输入操作符>> istream& operator>>(istream& is, vector<double>& vv) {double dd0.0;if(is >> dd)vv.p…

【如何训练一个中英翻译模型】LSTM机器翻译模型部署之ncnn(python)(五)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何训练…

Unity光照相关知识和实践 (烘焙光照,环境光设置,全局光照)

简介 本文将会通过一个简单的场景搭建&#xff0c;介绍如何使用烘焙光照以及相关的注意事项。另外还介绍了Unity内全局光照&#xff08;GI&#xff09;的知识和GI实际在游戏内的表现效果。 Unity关于光照相关的参考文档地址&#xff1a;https://docs.unity.cn/cn/current/Man…

Linux CentOS快速安装VNC并开启服务

以下是在 CentOS 上安装并开启 VNC 服务的步骤&#xff1a; 安装 VNC 服务器软件包。运行以下命令&#xff1a; sudo yum install tigervnc-server 输出 $ sudo yum install tigervnc-server Loaded plugins: fastestmirror, langpacks Repository epel is missing name i…

计算机论文中名词翻译和解释笔记

看论文中一些英文的简写不知道中文啥意思&#xff0c;或者一个名词不知道啥意思。 于是自己做了一个个人总结。 持续更新 目录 SoftmaxDeep Learning(深度学习)循环神经网络(Recurrent Neural Network简称 RNN)损失函数/代价函数(Loss Function)基于手绘草图的三维模型检索(Ske…

【笔记】PyTorch DDP 与 Ring-AllReduce

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 文内若有错误&#xff0c;欢迎指出&#xff01; 今天我想跟大家分享的是一篇虽然有点老&#xff0c;但是很经典的文章&#xff0c;这是一个在分布式训练中会用到的一项技术&#xff0c; 实际上叫ringallreduce。 …

用html+javascript打造公文一键排版系统8:主送机关排版

公文一般在标题和正文之间还有主送机关&#xff0c;相关规定为&#xff1a; 主送机关 编排于标题下空一行位置&#xff0c;居左顶格&#xff0c;回行时仍顶格&#xff0c;最后一个机关名称后标全角冒号。如主送机关名称过多导致公文首页不能显示正文时&#xff0c;应当将主送机…

redis的并发安全问题:redis的事务VSLua脚本

redis为什么会发生并发安全问题&#xff1f; 在redis中&#xff0c;处理的数据都在内存中&#xff0c;数据操作效率极高&#xff0c;单线程的情况下&#xff0c;qps轻松破10w。反而在使用多线程时&#xff0c;为了保证线程安全&#xff0c;采用了一些同步机制&#xff0c;以及多…

20.3 HTML 表格

1. table表格 table标签是HTML中用来创建表格的元素. table标签通常包含以下子标签: - th标签: 表示表格的表头单元格(table header), 用于描述列的标题. - tr标签: 表示表格的行(table row). - td标签: 表示表格的单元格(table data), 通常位于tr标签内, 用于放置单元格中的…

C语言枚举与联合体详解

本篇文章带来枚举与联合体相关知识详细讲解&#xff01; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作的动力之源&#xff0c;让我们一起加油&#xff0c;一起奔跑&#xff0c;让我们顶峰相见&#xff01;&#xff01;&#xff01; 目录 一…

InnoDB引擎底层逻辑讲解——架构之内存架构

1.InnoDB引擎架构 下图为InnoDB架构图&#xff0c;左侧为内存结构&#xff0c;右侧为磁盘结构。 2.InnoDB内存架构讲解 2.1 Buffer Pool缓冲池 2.2 Change Buffer更改缓冲区 2.3 Adaptive Hash Index自适应hash索引 查看自适应hash索引是否开启&#xff1a; show variable…

Modbus TCP/IP之异常响应

文章目录 一、异常响应二、异常码分析2.1 异常码0x012.2 异常码0x022.3 异常码0x032.4 异常码0x062.5 异常码0x04、0x05等 一、异常响应 对于查询报文&#xff0c;存在以下四种处理反馈&#xff1a; 正常接收&#xff0c;正常处理&#xff0c;返回正常响应报文&#xff1b;因为…

部署问题集合(十八)Windows环境下使用两个Tomcat

下载Tomcat Tomcat镜像下载地址&#xff1a;https://mirrors.cnnic.cn/apache/tomcat/进入如下地址&#xff1a;zip的是压缩版&#xff0c;exe是安装版 修改第二个Tomcat配置文件 第一步&#xff1a;编辑conf/server.xml文件&#xff0c;修改三个端口&#xff0c;有些版本改…

【Rust日报】2023-07-28 使用 Cargo-PGO 优化 Rust 程序

使用 Cargo-PGO 优化 Rust 程序 去年&#xff0c;作者致力于改进用于构建 Rust 编译器的配置文件引导优化 (PGO) 工作流程。在这样做的过程中&#xff0c;虽然 PGO 对于 Rust 工作得很好&#xff0c;但它并不像希望的那样易于使用和发现。这促使我创建了 cars-pgo&#xff0c;这…

【雕爷学编程】Arduino动手做(175)---机智云ESP8266开发板模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【Vue3】递归组件

1. 递归组件mock数据 App.vue <template><div><Tree :data"data"></Tree></div> </template><script setup lang"ts"> import { reactive } from vue; import Tree from ./components/Tree.vue; interface Tr…