Android 自定义View

我们所有的试图都是起源于自定义View,包括ViewGroup也是继承于它,可以说它是视图组件之父。
我们可以从它的大致流程来分为四个部分:
构造方法,onMeasure,onLayout,onDraw

构造方法:

它主要有四个构造方法
分别为:

  • View(Context context)
  • public View(Context context, @Nullable AttributeSet attrs)
  • public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
  • public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)

关于attrs,defSyleAttr,defStyleRes介绍,源码中是这样说的
(一) attrs
attrs是一个int值,通过它一系列xml中一系列属性值的一个
它的作用:

  • 可以通过它来获取布局文件资源id值
    在这里插入图片描述
  • 在saveAttributeData中会默认先加载系统默认的属性值跟id,然后通过attrs加载已解析的可样式属性,比如说layout_marginTop,系统会给它一个默认的值,如果我们在xml当中进行修改,然后会将原值进行替换。
    在这里插入图片描述
    在这里插入图片描述
    (二)defStyleAttr
    Framework中源文件参数的介绍:

defStyleAttr An attribute in the current theme that contains a reference to a style resource that supplies default values for the view. Can be 0 to not look for defaults.

(三)defStyleRes介绍

defStyleRes A resource identifier of a style resource that supplies default values for the view, used only if defStyleAttr is 0 or can not be found in the theme. Can be 0 to not look for defaults

这两个参数在saveAttributeDataForStyleable中有参与但是看不到具体的内容在这里插入图片描述

onMeasure

它最终会调到
MeasureSpec:
MeasureSpec是一个32位的int值,高2位代表SpecMode,低30位代表SpecSize,SpecMode是指测量模式,SpecSize是指某种测量模式下的规格大小。

  • EXACTLY 父容器已经检测出View所需要的精确大小,这时候View的最终大小就是SpecSize所指定的值。对应于LauoutParams中的match_parent和具体数值这两种模式。
  • AT_MOST 父容器指定了一个可用大小即SpecSize,View的大小不能大于这个值,对应于LayoutParams中的wrap_content
  • UNSPECIFIED 父容器不对View有任何限制,要多大给多大,常用于系统内部,平常工作中不常见

普通View的MeasureSpec的创建规则:
在这里插入图片描述
onMeasure会调到setMeasureDimension方法
在这里插入图片描述
它会设置View 宽/高的测量值,因此只需要看getDefaultSize方法
在这里插入图片描述从这个方法来看,View的宽高由specSize决定,再结合MeasureSpec的创建规则表,得出结论:
直接继承View的自定义控件需要重写onMeasure方法并设置wrap_content时的自身大小,否则在布局中使用wrap_content就相当于使用match_parent。因为 View使用wrap,它的specMode是AT_MOST模式,宽高等于specSize,这情况下specSize为parentSize,而parentSize是父容器可使用的大小。

解决方法:

        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {setMeasuredDimension(mWidth, mHeight);} else if (widthSpecMode == MeasureSpec.AT_MOST) {setMeasuredDimension(mWidth, heightMeasureSpec);} else if (widthSpecMode == MeasureSpec.AT_MOST) {setMeasuredDimension(widthMeasureSpec, mHeight);}

onLayout

onLayout主要是视图位置的确定

onDraw

View的回值过程遵循如下几步:

  1. 绘制背景 background.draw
  2. 绘制自己 onDraw
  3. 绘制child dispatchDraw
  4. 绘制装饰 onDrawScrollBars

常见Canvas方法:
在这里插入图片描述
Paint常用方法:

paint.setStrokeWidth(0);//设置画笔宽度0  ,单位px  默认一个像素
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);//描边 
paint.setStrokeWidth(10);//画笔宽度 10,单位px
paint.setAntiAlias(true);//抗锯齿功能
paint.setAlpha(); //设置画笔透明度
paint.setARGB();// 设置透明度 和 颜色
paint.setStyle()//设置画笔样式

注意:

  • 尽量不要在View中使用Handler
  • View中如果由线程或者动画,需要及时停止,可以在View#onDetachedFromWindow操作
  • 有嵌套滑动情形时,需要处理好滑动冲突

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

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

相关文章

如何判断一个js对象是否存在循环引用

一、背景 在前端JSON.stringfy是我们常用的一个方法,可以将一个对象序列化。 例如将如下对象序列化 const person { name: kalory, age:18}JSON.stringfy(person) // 结果 {"name":"kalory","age":18}将一个数组序列化const arr …

什么是分布式光伏系统?

随着全球对可再生能源和环保技术的日益重视,分布式光伏系统已成为电力领域中不可或缺的一部分。它代表了一种新兴的能源供应方式,具有显著的环保和经济价值。 一、定义与特点 分布式光伏系统是指将光伏组件安装在用户侧,如屋顶、墙面等建筑物…

ModuleNotFoundError: No module named ‘distutils‘的解决办法

最近想试试odoo17,在windows环境下,想安装试验一下,结果老出现oduleNotFoundError: No module named ‘distutils‘错误。查了一下,以为是python版本导致的,结果试了很多版本如下: 试了几个,每个…

Java——变量作用域和生命周期

一、作用域 1、作用域简介 在Java中,作用域(Scope)指的是变量、方法和类在代码中的可见性和生命周期。理解作用域有助于编写更清晰、更高效的代码。 2、作用域 块作用域(Block Scope): 块作用域是指在…

软考中级|软件设计师-知识点整理

目录 计算机网络概论 计算机系统基础知识 中央处理单元 数据表示 校验码 计算机体系结构 计算机体系结构的发展 存储系统 输入/输出技术 安全性、可靠性与系统性能评测基础知识 加密技术和认证技术 计算机可靠性 程序设计语言基础知识 程序设计语言概述 程序设计…

微信同声传译小程序插件使用教程

微信同声传译小程序插件 —— 机器翻译、智能语音 案例可搜索“一起学英语鸭”小程序查看, 实现效果如下图: 插件功能 语音转文字 语音合成 文本翻译 step 1:添加插件 在使用前,需要登录官网 设置 → 第三方服务 → 添加插件…

Hadoop的读写流程

Hadoop分布式文件系统(HDFS)是Apache Hadoop项目的核心组件,它为大数据存储提供了一个可靠、可扩展的存储解决方案。本文将详细介绍HDFS的读写数据流程,包括数据的存储原理、读写过程以及优化策略。 一、HDFS简介 HDFS是一个高度容错的分布式文件系统,它设计用于运行在通…

AI探索:最佳落地应用场景

如果说今年的风口,那一定是 AI。不过AI像一把双刃剑,既有助益也有风险。我们将从IBM Watson的高飞与坠落,到Google Allo的黯然失色,探索AI应用中的教训。同时,瑞幸咖啡的成功故事展现了凭借策略得当的AI应用&#xff0…

2024年【安全员-C证】考试资料及安全员-C证找解析

题库来源:安全生产模拟考试一点通公众号小程序 安全员-C证考试资料根据新安全员-C证考试大纲要求,安全生产模拟考试一点通将安全员-C证模拟考试试题进行汇编,组成一套安全员-C证全真模拟考试试题,学员可通过安全员-C证找解析全真…

探索AI创新的前沿——从零开始学习和运用SpringAI

1.SpringAI介绍 SpringAI是AI工程师的一个应用框架,它提供了一个友好的API和开发AI应用的抽象,旨在简化AI应用的开发工序。 目标是将可移植性和模块化设计等设计原则应用于AI领域的Spring生态系统,并将POJO作为应用程序的构建块推广到AI领域…

浅谈赚钱的四个级别,你在哪一层呢

一谈到赚钱,很多人都会扯到:智商、情商、人脉、资源、背景等等,类似“小钱靠勤,中钱靠智,大钱靠德”这样的经典语录都会脱口而出,其实从本质上来讲,都没有错,但这样的说法太缥缈&…

mysql-connector下载教程(手把手)

下载一个第三方库主要有三种途径: 去官方网站 Oracle 官网去github去Maven中央仓库 前两个方法比较麻烦,你还需要去找。 这里就只介绍maven的方法 Maven类似于手机app的应用商店。 操作步骤: 点击右边进入官网Maven中央仓库 在搜索框中…

k8s+pv+pvc+nas 数据持久化volumes使用

1 k8s pod申请持久化卷配置 apiVersion: v1 kind: Service metadata:name: $IMG_NAMEnamespace: rz-dtlabels:app: $IMG_NAME spec:type: NodePortports:- port: 8091nodePort: 31082 #service对外开放端口selector:app: $IMG_NAME --- apiVersion: apps/v1 kind: Deployment …

FineReport简单介绍(2)

一、报表类型 模板设计是 FineReport 学习过程中的主要难题所在,FineReport 模板设计主要包括普通报表、聚合报表、决策报表三种设计类型。 报表类型简介- FineReport帮助文档 - 全面的报表使用教程和学习资料 二、聚合报表 2-1 介绍 聚合报表指一个报表中包含多个…

机器学习笔记 - 用于3D点云数据分割的Point Net的训练

一、数据集简述 ​在本教程中,我们将学习如何在斯坦福 3D 室内场景数据集 ( S3DIS )上训练 Point Net 进行语义分割。S3DIS 是一个 3D 数据集,包含来自多栋建筑的室内空间点云,占地面积超过 6000 平方米。Point Net使用整个点云,能够执行分类和分割任务。如果你一直在关注 …

openstack搭建

openstack搭建 1、虚拟机部署规划 主机主机名IP规划实例通讯内部通讯控制节点controller192.168.10.144192.168.1.144实例节点compute192.168.10.145192.168.1.145 2、硬件配置 主机名内存逻辑CPU数量硬盘容量controller4G480Gcompute4G480G20G 3、安装centos7&#xff0c…

Science:如何快速完成一篇研究性论文?

我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 完成一篇研究性论文,是将长时间积累的研究成果凝聚在几页纸中,对资深科学家而言也是一大挑战。作者们需要在充分论述科学问题和详细展示结果之间找到平…

javaweb 期末复习

1. JDBC数据库连接的实现逻辑与步骤以及JDBC连接配置(单列模式) public class JDBCUtil {// 这些换成自己的数据库 private static final String DB_URL "jdbc:mysql://localhost:3306/你的数据库名称";private static final String USER &q…

linux中批量给文件改名

rename 需要批量将文件名前的UC-10_取消掉,以数字来命名文件 rename s/UC-10_// *.jpg 修改成功 要是修改为其他名字需要在单引号的第二个/后加字符即可 例如要改为li

基于 SSM 框架的二手书交易系统

基于 SSM 框架的二手书交易系统 一、项目介绍二、项目技术栈三、项目运行四、项目演示总结 大家好,这里是程序猿代码之路。在当今环保意识日益增强和资源节约型社会建设的背景下,二手交易作为一种节省资源和降低成本的消费方式越来越受到人们的欢迎。特别…