android——自定义TextView

news2024/11/20 1:40:10

效果展示:

在这里插入图片描述

代码解析:

1、首先设置自定义属性(res/values下新建一个attrs.xml文件)

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!--    name 自定义view的名字  CustomTextView-->
    <declare-styleable name="CustomTextView">
        <!--        name 属性名称  format:格式

                    string:文字   color:颜色
                    dimension: 宽高,字体大小
                    integer:数字  reference:资源(drawable)

        自定义属性不能和系统有的属性重名(如:textview有text属性,自定义的name不能使用name)
        -->
        <attr name="iText" format="string" />
        <attr name="iTextColor" format="color" />
        <attr name="iTextSize" format="dimension" />
        <attr name="iMaxLength" format="integer" />
<!--        自定义view都是继承自view,背景由view管理,所以iBackground可以去掉-->
<!--        <attr name="iBackground" format="reference|color" />-->

        <!--枚举-->
        <attr name="iTnputType">
            <enum name="number" value="1" />
            <enum name="text" value="2" />
            <enum name="password" value="3" />
        </attr>
    </declare-styleable>

</resources>

2、需要创建一个类继承自view ,重写构造方法

public class CustomTextView extends View {
    private String mText;
//    字体默认大小(像素)
    private int mTextSize=18;  
//    默认颜色
    private int mTextColor= Color.BLUE;

//   画笔
    private Paint mPaint;

//    在new的时候调用
    public CustomTextView(Context context) {
        this(context,null);
    }

//    在布局Layout中使用
    public CustomTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

//    在style中使用
//    @style="style/default"
    public CustomTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);

        mText=array.getString(R.styleable.CustomTextView_iText);
        mTextColor=array.getColor(R.styleable.CustomTextView_iTextColor,mTextColor);
        mTextSize=array.getDimensionPixelSize(R.styleable.CustomTextView_iTextSize,sp2px(mTextSize));
        array.recycle(); //回收TypedArray

        mPaint=new Paint();
        mPaint.setAntiAlias(true); //抗锯齿
        mPaint.setStyle(Paint.Style.FILL); //空心
        mPaint.setTextSize(mTextSize); // 画笔大小
        mPaint.setColor(mTextColor); //颜色
    }

3、onMeasure中测量尺寸

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//        获取宽高的模式
       int widthMode=MeasureSpec.getMode(widthMeasureSpec);
       int heightMode=MeasureSpec.getMode(heightMeasureSpec);

 //    1、 获取宽高的值 EXACTLY模式不需要计算直接测量,给多少就是多少

       int widthSize=MeasureSpec.getSize(widthMeasureSpec);
       int heightSize=MeasureSpec.getSize(heightMeasureSpec);

//     2、At_MOST模式是wrap_content 需要计算

       if (widthMode==MeasureSpec.AT_MOST){
//           计算的宽度与字体的长度和字体的大小有关  用画笔来测量
           Rect bounds=new Rect();
//           获取文本的Rect(矩形)
           mPaint.getTextBounds(mText,0,mText.length(),bounds);
           // getPaddingStart()+getPaddingEnd()不添加这个在页面布局中添加padding值是无效的
           widthSize=bounds.width()+getPaddingStart()+getPaddingEnd();
       }

        if (heightMode==MeasureSpec.AT_MOST){
//           计算的宽度与字体的长度和字体的大小有关  用画笔来测量
            Rect bounds=new Rect();
//           获取文本的Rect(矩形)
            mPaint.getTextBounds(mText,0,mText.length(),bounds);
            heightSize=bounds.height()+getPaddingTop()+getPaddingBottom();
        }
//        设置控件的宽高
       setMeasuredDimension(widthSize,heightSize);
    }

4、绘制

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        画弧
//        canvas.drawArc();
        画圆
//        canvas.drawCircle();
//        画文字  text,x,y,paint
//        x: 开始的位置
//        y:基线  baseLine
//        dy:代表高度的一半到baseLine的距离
        Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
//        top是一个负值,bottom是一个正值(可以打印看正负值)
//        bottom:是baseLine到文字底部的距离
//        top是baseLin到文字顶部的距离
         int dy=(fontMetricsInt.bottom-fontMetricsInt.top)/2-fontMetricsInt.bottom;
         int baseLine=getHeight()/2+dy;
        int x=getPaddingStart();
        canvas.drawText(mText,x,baseLine,mPaint);
        画线
//        canvas.drawLine();
    }

5、布局文件中使用
(要在父布局添加 xmlns:myApp=“http://schemas.android.com/apk/res-auto” )

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:myApp="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.myviewstudy.CustomTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        myApp:iText="名字abcdefgh"
        myApp:iTextColor="#FF0000"
        myApp:iTextSize="20sp"
        android:padding="10dp"
        android:background="@color/teal_700"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flask文件夹列表改进版--Bug追踪

把当前文件夹下的所有文件夹和文件列出来&#xff0c;允许点击返回上层目录&#xff0c;允许点击文件夹进入下级目录并显示此文件夹内容 允许点击文件进行下载 from flask import Flask, render_template, send_file, request, redirect, url_for import osapp Flask(__name_…

51单片机(STC8)-- 串口配置及串口重定向(printf)

文章目录 STC8串口概述串口寄存器配置串口1控制寄存器SCON串口1数据寄存器SBUF串口1模式 1工作方式串口1波特率计算方式 串口注意事项串口1通信demo串口重定向 STC8串口概述 由下图可知STC8H3K64S4带有4个4个串行通信接口&#xff0c;芯片名后两位S所带的数字即代表这款芯片带…

Systemctl | 系统服务管理利器

功能介绍 systemctl 是用于管理系统服务的命令行工具&#xff0c;常用于 Linux 系统中。提供了对系统服务&#xff08;包括启动、停止、重启、启用、禁用等&#xff09;的控制&#xff0c;以及对系统单元&#xff08;units&#xff09;的操作。 语法结构 systemctl 的基本语…

burpsuite的安装与介绍

安装(挑一个你喜欢的版本安装就行) 编程环境安装指南:Java、Python 和 Burp Suite抓包工具_burpsuite和java-CSDN博客 简介 Burp Suite是一个用于攻击Web应用程序的集成平台。它集成了多种渗透测试组件,能够帮助我们更好地完成对Web应用的渗透测试和攻击,无论是自动化还…

记一次Mac端mysql重置密码

在执行mysql命令的时候&#xff0c;报如下的错误&#xff0c;表示不支持mysql命令&#xff1a; zsh: command not found: mysql 1. 先查看mysql服务是否存在 在系统偏好设置中查看&#xff1a; 2. 发现mysql服务已经在运行&#xff0c;可能因为/usr/local/bin目录下缺失mysq…

信号处理设计模式

问题 如何编写信号安全的应用程序&#xff1f; Linux 应用程序安全性讨论 场景一&#xff1a;不需要处理信号 应用程序实现单一功能&#xff0c;不需要关注信号 如&#xff1a;数据处理程序&#xff0c;文件加密程序&#xff0c;科学计算程序 场景二&#xff1a;需要处理信…

Xshell连接不上本地虚拟机中的linux处理

0、连接不上虚拟机的原因 1、本地电脑未启用VMware网络。 2、连接协议选择错误。 3、防火墙屏蔽IP。 4、虚拟机网络连接模式不是桥接模式。 1、查看本地是否启用VMware的网络 2、连接协议选择 我们在新建会话时&#xff0c;可选的协议有FTP和SFTP两种&#xff0c;其中FTP采用21…

uniapp 手持弹幕全端实现(微信/QQ小程序 + APP)

见下述效果图,本文话少纯干货 代码实现 <template><view class="main"

【RocketMQ笔记02】安装RocketMQ可视化工具rocketmq-dashboard

这篇文章&#xff0c;主要介绍如何安装RocketMQ可视化工具rocketmq-dashboard。 目录 一、RocketMQ可视化界面 1.1、下载rocketmq-dashboard 1.2、修改配置文件 1.3、打包工程 1.4、启动rocketmq-dashboard 一、RocketMQ可视化界面 1.1、下载rocketmq-dashboard rocketm…

NET中使用Identity+CodeFirst+Jwt实现登录、鉴权

目录 前言 一、创建上下文类 1.自定义MyContext上下文类继承IdentityDbContext 2.在Program中添加AddDbContext服务 二、使用Migration数据迁移 1.在控制台中 依次使用add-migration 、updatebase 命令 2.如何修改表名 3.如何自定义字段 三、使用Identity实现登录、修改密码 …

汽车零配件装配产线中使用RFID技术和不使用RFID技术的优缺点

汽车零配件装配产线中使用RFID技术和不使用RFID技术的优缺点 RFID(射频识别技术)是非接触式自动识别技术&#xff0c;经常被使用于工业制造、物流管理、仓储物品盘点等领域。我们聊一聊在汽车零配件装配产线中使用和不使用RFID技术的优缺点 在汽车零配件装配线使用RFID技术可以…

「GPT」G、P、T分别是啥意思?

G意为Generative &#xff1a;生成式 比如&#xff0c;生成式的分类器&#xff08;模型&#xff09;包括---- generative classifiers: naive Bayes classifier and linear discriminant analysis 与之对应的为判别式----- discriminative model: logistic regression P意为…

每日一题——LeetCode206.反转链表

个人主页&#xff1a;白日依山璟 专栏&#xff1a;Java|数据结构与算法|每日一题 文章目录 1. 题目描述示例1示例2示例3提示 2. 思路3.代码 1. 题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例1 输入&#xff1a;head [1…

讯飞星火认知大模型智能语音交互调用

随着国内外大模型热度的兴起&#xff0c;依托于大模型的智能化&#xff0c;传统的人机交互已经不能满足人们交互的需求。而结合语音和大模型的交互拜托传统互联网获取知识的文字限制&#xff0c;用语音也可以轻松获取想要的知识和思路。 一、大模型智能语音交互调用实现思路 …

nginx-proxy-manager初次登录502 bad gateway

nginx-proxy-manager初次登录502 bad gateway 按照官方docker-compose安装后,页面如下: 默认账户密码: adminexample.com/changeme点击sign in,提示Bad Gateway 打开调试 重装后依然如此,最后查阅githup issue 找到答案 https://github.com/NginxProxyManager/nginx-proxy-…

16.Redis 高级数据类型 + 网站数据统计

目录 1.Redis 高级数据类型 2.网站数据统计 2.1 业务层 2.2 表现层 2.2.1 记录数据 2.2.2 查看数据 1.Redis 高级数据类型 HyperLogLog&#xff1a;采用一种基数算法&#xff0c;用于完成独立总数的统计&#xff1b;占据空间小&#xff0c;无论统计多少个数据&#xff0…

Oraclelinux部署Oracle服务

采用图形化界面 user用户 oracle用户 #清屏 clear #设置主机名 hostnamectl set-hostname ceshidb sed -i 1,2 s/^/#/ /etc/hosts echo "127.0.0.1 ceshidb" >> /etc/hosts echo "::1 ceshidb" >> /etc/hosts ping -c 5…

STM32F4系列单片机库函数模板工程创建

目录 一、工程配置 1、新建工程 2、芯片选择 3、工程子文件夹创建 &#xff08;1&#xff09;FWLIB文件夹添加文件 &#xff08;2&#xff09;CORE文件夹添加文件 &#xff08;3&#xff09;USER文件夹添加文件 4、工程设置 &#xff08;1&#xff09;工程中添加文件夹…

记一次redis内存没满发生key逐出的情况。

现象&#xff1a; 从监控上看&#xff0c;redis的内存使用率最大是80%&#xff0c;但是发生了key evicted 分析&#xff1a; 原因1、可能是阿里云监控没抓取到内存100%监控数据。 阿里控制台监控监控粒度是5秒。 内存使用率的计算方法。 used_memory_human/maxmemory 原因2、…

uniapp APP应用程序iOS没有上架到苹果应用商店如何整包更新?

随着移动互联网的快速发展&#xff0c;uni-app 作为一种跨平台开发框架&#xff0c;受到了广泛欢迎。然而&#xff0c;有时候开发者可能会遇到一个问题&#xff1a;如何为已经发布到苹果应用商店的 uni-app APP 进行整包更新&#xff1f;尤其是当应用还没有上架到苹果应用商店时…