Android自定义控件(三)---实战篇(详解onMeasure)

2023-11-02

接着Android自定义控件(二)---实战篇的讲解,这篇我们来详细讲一下测量(onMeasure)和绘制(onDraw)这两个方法

首先,我们来看测量(onMeasure)方法,在这个方法里,我们主要是设置控件的宽高,widthMeasureSpec、heightMeasureSpec这两个参数已经在基础篇讲解了,不过多赘述Android自定义控件(一)---基础篇

package com.example.mytextview;

//import javax.swing.text.View;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

public class mTextView extends View {
    //1、设置自定义属性变量
    private int mTextSize = 16;
    private int mTextColor = Color.RED;
    private String mText;

    //设置文字画笔
    private Paint textPaint;

    public mTextView(Context context) {
        this(context,null);
    }

    public mTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public mTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //2、获取装有自定义属性值的数值
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.mTextView);
        //3、精确获取自定义属性值
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.mTextView_mTextSize,mTextSize);//源码用的这个方法,参照 TextView
        mTextColor = typedArray.getColor(R.styleable.mTextView_mTextColor,mTextColor);
        mText = typedArray.getString(R.styleable.mTextView_mText);
        //4、回收 typedArray
        typedArray.recycle();

        initData();
    }

    private void initData() {
        textPaint = new Paint();
        //抗锯齿
        textPaint.setAntiAlias(true);
        //设置颜色
        textPaint.setColor(mTextColor);
        //设置字体大小
        textPaint.setTextSize(mTextSize);
    }

    //5、测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取宽高
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        //获取模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //判断 如果是 wrap_content 模式,则 布局宽高 与 字体大小和字体长度有关
        if(widthMode == MeasureSpec.AT_MOST){
            //设置文字边界
            Rect bounds = new Rect();
            //获取文字边界
            textPaint.getTextBounds(mText,0,mText.length(),bounds);
            //获取边界宽度  ===  获取文字宽度
            width = bounds.width();
        }
        if (heightMode == MeasureSpec.AT_MOST){
            //设置文字边界
            Rect bounds = new Rect();
            //获取文字边界
            textPaint.getTextBounds(mText,0,mText.length(),bounds);
            //获取边界高度  ===  获取文字高度
            height = bounds.height();
        }
        //最后设置宽高
        setMeasuredDimension(width,height);
    }

    //6、绘制
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

现在可以去运行一把了,可以看到一个方块,之所以没有汉字,是因为我们没有编写绘制(onDraw)方法,效果图如下:

在这里,我还想多说一句,那就是内边距(padding)和外边距(margin)对布局尺寸的影响

padding会使布局宽高增加,并且会继承布局的背景色,如果布局使用的是  match_parent 还会导致布局超出屏幕

margin会使布局宽高减少,并且不会继承布局的背景色

这点不做要求,你们碰见问题之后知道怎么解决接好了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android自定义控件(三)---实战篇(详解onMeasure) 的相关文章

  • Android 原生 AAssetManager 的文件层次结构

    Issue 我想知道如何从本机代码创建 Android 中资产文件夹的文件层次结构 我在用着AAssetManager openDir but AAssetDir getNextFileName不返回任何目录名称 因此基本上我无法深入了解层
  • Play Framework 2.5.1 路由和依赖项注入(适用于 Java)

    我的 路线 文件中有这个 POST accounts controllers AccountsController createOneAccount 在我的 AccoutsController java 中 package controll
  • 如何以编程方式设置 ConstraintLayout 的 XML 属性“layout_constrainedWidth”?

    ConstraintLayout中 如何转换xml属性 app layout constrainedWidth true false in code 如果你想设置constrainedWidth Height以编程方式 那么你必须采取Con
  • 设置 ViewGroup 的最大宽度

    如何设置 ViewGroup 的最大宽度 我正在使用一个Theme Dialog然而 当调整大小到更大的屏幕时 它看起来不太好 它也有点轻量级 我不希望它占据整个屏幕 I tried 这个建议 https stackoverflow com
  • 我可以直接在 Maven 中使用 GitHub 项目吗?

    我有兴趣使用GitHub 上的项目 https github com toelen spymemcached jcache作为我的项目中的依赖项 GitHub 项目有一个pom文件 我可以修改我的pom文件来使用这个项目 如果是这样 怎么办
  • 当我单击 GridView 项时返回 ImageView 实例

    当我点击GridView项时如何返回ImageView实例 我为 ItemClick 创建自定义绑定事件 public class ItemClickSquareBinding MvxBaseAndroidTargetBinding pri
  • 如果从超链接打开,应用程序将启动两次

    我正在开发一个应用程序 可以从多个地方启动 例如日历中的超链接 我在以下场景中面临问题 如果应用程序已启动并在后台运行 并且用户单击本机日历中的事件 超链接来启动应用程序 我的应用程序作为新实例启动两次 在正在运行的应用程序列表中 我可以看
  • 更改 WireMock __files 目录

    来自docs http wiremock org docs stubbing 要从文件中读取正文内容 请将文件放在 files 下 目录 默认情况下 这应该位于 src test resources 下 从 JUnit 规则运行时 当独立运
  • 以编程方式卸载 Android 应用程序

    我希望能够允许我的用户从我的应用程序中卸载应用程序 就像 Google Play 商店允许其用户一样 请下图 主要问题是如何定义一个按钮 按下它我们可以通过提供包名称或其他一些信息来卸载应用程序 就像图像上的卸载按钮一样 try Inten
  • 调整 Java 类以提高 CPU 缓存友好性

    在设计java类时 对于实现CPU缓存友好性有哪些建议 到目前为止我学到的是应该尽可能多地使用 POD 即 int 而不是整数 这样 在分配包含对象时 数据将被连续分配 例如 class Local private int data0 pr
  • AWS Lambda 和 S3 - 上传的 pdf 文件为空/损坏

    我有一个 Spring 应用程序 在 AWS Lambda 上运行 它获取文件并将其上传到 AWS S3 Spring控制器发送一个MultipartFile到我的方法 使用 Amazon API Gateway 将其上传到 AWS S3
  • 计算事件之间的天数 - Android

    我一直在研究 Android API 并一直在寻找一种方法来计算当前日期和未来日期之间的天数 我对 android 还很陌生 而且我已经有几年没有做过 java 了 计算这个最简单的方法是什么 Thanks 最简单的方法是使用乔达时间 ht
  • 为什么 writeObject 抛出 java.io.NotSerializedException 以及如何修复它?

    我有这个异常 我不明白为什么会抛出它 或者我应该如何处理它 try os writeObject element catch IOException e e printStackTrace Where element is a Transf
  • JPA中如何连接多个数据库?

    我有一个 Spring Boot 应用程序 当前使用 JPA 连接到单个数据库 application properties 文件中的连接详细信息 spring datasource url jdbc oracle thin localho
  • 尝试在后台使用 AsyncTask 解析 JSON 时强制关闭

    我是 Android 开发新手 正在研究 json 数据 我设法让解析工作 我想显示一个 ProgressDialog 我读到我需要使用 AsyncTask 但由于某种原因 一旦我将相同的工作代码放入 doInBackground 中 即使
  • 需要使用自定义类而不是在 Web 服务中生成(通过 wsimport)

    您能帮忙解决以下问题吗 当生成 WS 客户端代码 使用 wsimport ant 任务 时 所有类都会在与 Web 服务相同的包 例如 helloservice endpoint 中自动生成 例如如果我的网络服务有方法 公共节点 getNo
  • Android smoothScrollTo 不调用 onScrollStateChanged

    我在用smoothScrollBy 滚动到 a 中的特定位置ListView 我希望在以下情况时得到通知ListView完成滚动以将其与当前集成onScrollStateChanged 当用户用手指滚动时触发的事件 目前我正在使用Timer
  • 有没有办法让 SonarQube 只警告不完整的 Switch 语句?

    使用 Java SonarQube 抱怨枚举值上的 switch 语句没有default case 给出的推理是 最终默认条款的要求是防御性编程 该条款应采取适当的行动 或包含 关于为什么不采取行动的适当评论 当开关盖上时 枚举的所有当前值
  • 切换按钮形状不变

    我正在尝试制作一个带有绿色背景的圆形切换按钮 我用了
  • 在 Android 上提取/修改视频帧

    我有一个视频文件 我想获取视频的每一帧并对帧进行一些修改 例如在其中绘制另一个位图 放置一些文本等 Android 中是否有任何 API 框架可用于从视频中获取帧 我在 iOS 中使用他们的 AVFramework 做了类似的事情 如果可以

随机推荐

  • 【数模研赛】“华为杯”第十九届中国研究生数学建模竞赛C题分享——(四)问题二模型建立

    写在前面 第十九届数模研赛在22年10月6 10日开展 我和我的两名队友肝了5天 整出来一篇论文 因为不确定自己做的好不好 所以一直没写博客 前两天结果出来了 我们队拿了国二 在C题里排名88 1134 感觉结果还不错 以后应该也不会再有机
  • UE4 实现控制场景中所有物体透明度功能

    本文会讲解如何利用材质参数集简单的实现修改场景中所有物体透明度的功能 讲解地图为第三人称地图 1 创建材质变量集 这里面新建的变量可以在蓝图中控制 这样就能很方便的修改透明度 因为透明度是只有一个值的参数所以创建scalar参数 默认值为1
  • c语言的product,张永强:C语言中product是什么意思

    吴俊光的回答 product在C语言中不是关键字 C库中也没有这样的函数名 所以pruduct有两种可能 1是编程者自己定义的变量 2是编程者自定义的函数的名字 这里product是自定义函数的名字 功能就是返回a乘b的结果 实现一个乘法功
  • 【转载】Linux下用ls和du命令查看文件以及文件夹大小

    1 ls的用法 ls ll 列出当前目录下所有文件的大小以及所有文件大小的统计总和 显示成字节大小 ls lh 列出当前目录下所有文件的大小以及所有文件大小的统计总和 以KB MB等为单位进行显示 ls l grep wc l 或 find
  • 基于BCM53262交换芯片平台的Linux操作系统移植(四)之代码调试与驱动书写

    2018 05 09 10 49 zhoulinhua 2018 05 10 一 系统分区 name address size bootstrap 0x0 64k u boot 0x10000 640k env 0xb0000 192k d
  • 【C语言】练习题 - 菲姐游泳 - 附视频讲解

    游泳奥运冠军菲姐刻苦训练 从早上a时b分开始下水训练 直到当天的c时d分结束 请编程计算 菲姐当天一共训练多少小时多少分钟 本文引用自作者编写的下述图书 本文允许以个人学习 教学等目的引用 讲授或转载 但需要注明原作者 海洋饼干叔 叔 本文
  • 独立按键消抖与松手检测

    记录下最近独立按键消抖和松手检测 我对独立按键的处理思路是 1 获得键值 2 消抖处理 3 松手检测 4 键值解析 1 获得键值 这里把独立按键做个编号 例如有两个按键记为KEY0 KEY1 用一个变量来记录当前按键标记值 比如Cur Ke
  • npm install 编译时报“Cannot read properties of null (reading ‘pickAlgorithm‘)“

    先看报错 先说下网上大多数的解决方案 方案一 重新安装node解决 方案二 删了node models重新下 或者直接下载CNPM 淘宝镜像 进行安装 CNPM安装办法 npm install g cnpm registry https r
  • 解决STM32驱动0.96OLED不亮的问题

    问题描述 使用STM32无法驱动OLED 解决方案 1 检查硬件连接是否有误 OLED STM32 VCC 5V或3 3V SDA SDA SCL SCL GND GND 备注 最好接STM32最小系统版的3 3V 当连接STM32最小系统
  • Javaio流

    io流 关于Java的io流一般按照数据操作类型可以分为字节流与字符流 首先来说一下字节流 字节流 字节流的方法都是以stream结尾的 字节流的用途 转换图片为二进制 转换音频 视屏为二进制 字符串等也可以转为二进制 字节流常用于图片 音
  • 签到题【牛客算法周周练6E】【暴力枚举+线段树】

    题目链接 题目保证数据随机 数据随机真的是太强了 直接可以跑最坏时候是的复杂度 直接暴力建线段树 然后更新的时候更新到底 查询的时候也是查询到底 因为数据随机 所以其实被处理的次数是很少的 因为要刚好是set里有的 或者是set里没有的 这
  • Unity3D-----三维数学(向量)

    Unity3d gt 三维数学之向量 一 向量 1 什么是向量 2 向量的形式 3 向量的大小 4 向量的方向 二 向量运算 1 向量相减 2 向量相加 3 向量与标量的乘除法 4 点乘 5 叉乘 三 三角函数 1 角的度量单位 2 三角函
  • Labelme 目标检测和语义分割的数据标注

    1 安装labelme 打开conda prompt 输入以下代码创建虚拟环境 打开虚拟环境 安装lelme conda create n labelme python 3 6 创建虚拟环境 conda activate labelme 打
  • 解决idea出现报错:Error running,Command line is too long. Shorten command line

    报错的原因 因为项目需要打印的环境变量太长 超过了限制 需要缩短命令行来解决问题 解决办法 方法一 Edit Configurations 将默认的Shorten command line的值user local default 改为 JA
  • 格式工厂多个图片合并成一个PDF的报错

    使用图片合并PDF功能时 当图片数量超过50会报错 找到imgconv py文件 将50改为500 保存 现在可以支持100张图合并成一个PDF文件了 但是超过150张程序会直接闪退 正在解决中 补充说明 1 如何设置PDF压缩比 打开 g
  • 有奖调研

    简介 感谢您一直以来对阿里云通信短信服务的支持 为了提升用户体验 为您在数字化转型的通信之路提供助力 云通信短信服务将发起一次满意度调研 有关短信服务 无论使用情况 抑或功能需求 还是文档 产品介绍页 计算与账单 控制台 API SDK 售
  • TypeError Cannot read properties of undefined (reading ‘matched‘)vue项目创建之后写路由报错

    vue项目创建之后写路由报错 原代码 修改之后代码 在 import 路由文件后 命名为Router 就会出现报错 原因 router 才是Vue实例化的配置字段名称 不识别其他的
  • Linux下访问数据库

    Linux下访问数据库 声明 本文只简单描述Linux系统下访问mysql数据库的步骤 关于连接上数据库之后的简单的对于数据库的增删改查等操作只是稍微提及 关于增删改查的语句书写 本文不再讲述 一般来说 访问数据库有如下几个步骤 1 初始化
  • C#控制台程序中使用log4.net来输出日志

    Apache log4net 库是一个帮助程序员将日志语句输出到各种输出目标的工具 log4net 是优秀的 Apache log4j 框架到 Microsoft NE T 运行时的端口 我喜欢他可以自定义输出 区分等级等特点 导入库 我们
  • Android自定义控件(三)---实战篇(详解onMeasure)

    接着Android自定义控件 二 实战篇的讲解 这篇我们来详细讲一下测量 onMeasure 和绘制 onDraw 这两个方法 首先 我们来看测量 onMeasure 方法 在这个方法里 我们主要是设置控件的宽高 widthMeasureS