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 …

什么是分布式光伏系统?

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

OperationalError: (_mysql_exceptions.OperationalError)

OperationalError: (_mysql_exceptions.OperationalError) (2006, MySQL server has gone away) 这个错误通常表示客户端(例如你的 Python 程序使用 SQLAlchemy 连接到 MySQL 数据库)和 MySQL 服务器之间的连接被异常关闭了。这个问题可能由多种原因引起,以下是一些常见的原…

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

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

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

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

windows设备/路由设备上ip地址如何查看、使用

在Windows设备上查看本地IP地址(IPv4和IPv6): 使用命令提示符: 打开命令提示符(在Windows中按Win R,然后输入"cmd"并按Enter)。在命令提示符窗口中,输入以下命令以查看…

Redis缓存穿透、缓存雪崩和缓存击穿的解决方案

Redis缓存穿透、缓存雪崩和缓存击穿的解决方案 引言 Redis作为当前非常流行的内存数据结构存储系统,以其高性能和灵活性被广泛应用于缓存、消息队列、排行榜等多种场景。然而,在实际使用过程中,可能会遇到缓存穿透、缓存雪崩和缓存击穿等问…

软件服务中的 SLA 到底是什么?

目录 什么是 SLA SLA 的组成部分 SLA 的重要性 制定和执行 SLA 小结 平常使用云服务或者使用 SaaS 服务时,厂商一般都会承诺 SLA 达到多少,没有达到的话会如何赔偿,例如云服务的稳定性一般会承诺4个9(即99.99%)。…

C语言:进程

一、进程标识符pid 类型pid_t,16位整型数三万多个。2的16次方65535. 进程标识是顺次向下使用。与文件描述符不一样。 pid_t getpid(void); pid_t getppid(void); 进程正常终止 1.从main函数返回 2.调用exit 3.调用_exit或_Exit 4.最后一个线程…

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

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

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

微信同声传译小程序插件 —— 机器翻译、智能语音 案例可搜索“一起学英语鸭”小程序查看, 实现效果如下图: 插件功能 语音转文字 语音合成 文本翻译 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证找解析全真…

自学前端第一天

HTML标签 ’HTML‘全程是‘hypertext Markup langage(超文本标记语言) HTML通过一系列的’标签(也称为元素)‘来定义文本、图像、链接。HTML标签是由尖括号包围的关键字。 标签通常成对存在,包括开始标签和结束标签(也称为双标签…

探索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 介绍 聚合报表指一个报表中包含多个…