基础巩固(六)自定义View

news2024/9/20 21:23:53

文章目录

  • View绘制流程
    • Measure
    • Layout
    • Draw
  • 自定义View的实现的步骤
    • 步骤1:实现Measure、Layout、Draw流程
      • 自定义 Measure
        • ViewGroup.LayoutParams
        • MeasureSpec
      • 自定义Layout
    • 自定义属性
  • 绘制工具类
    • Paint
      • 具体使用
    • Path
    • Canvas

View绘制流程

在这里插入图片描述
在绘制前,系统会有一些绘制准备,创建PhoneWindow,DecorView,ViewRootImpl。这个过程在Activity的onCreate()。

View的绘制流程开始于 ViewRootImpl对象的performTraversals()

/**
  * 源码分析:ViewRootImpl.performTraversals()
  */
  private void performTraversals() {
  		// 1. 执行measure流程
        // 内部会调用performMeasure()
        measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight);

        // 2. 执行layout流程
        performLayout(lp, mWidth, mHeight);

        // 3. 执行draw流程
        performDraw();
    }

View绘制流程从顶级View(DecorView)的ViewGroup开始,一层一层从ViewGroup至子View遍历测绘:measure、layout、draw。
在这里插入图片描述

  • 从根视图开始,深度优先搜索遍历每个子view执行measure

  • 从根视图开始,深度优先搜索遍历每个子view执行layout

  • 从根视图开始,深度优先搜索遍历每个子view执行draw

在这里插入图片描述

Measure

measure的作用是测量View的宽 / 高
在一些情况下,视图的尺寸受到动态内容、响应式设计、布局约束或动画效果的影响时,可能需要进行多次测量才能确定最终的宽度或高度,因此measure过程得到的 宽 / 高可能不准确,建议在layout过程中的onLayout去获取最终的宽 / 高。

单一view的measure过程:

  • measure():基本测量逻辑的判断
  • onMeasure():分为两步
    • getDefaultSize():根据View宽 / 高测量规格计算View的宽高值
    • setMeasure():存储测量后的子view宽 / 高

ViewGroup的measure流程:

注意:ViewGroup的measure过程中,等待所有的子view都measure完毕,合并所有子view的尺寸才可以得到ViewGroup父视图的测量值。

在这里插入图片描述

Layout

Layout过程的作用是计算视图View的位置,即
View的四个顶点位置:Left、Top、Right 和 Bottom。
在这里插入图片描述

Draw

Draw过程的作用是绘制View视图
单一View只需要绘制自身(含背景、内容)和装饰。

注意:这里的装饰指的是指示器、滚动条和前景

ViewGroup的绘制包括:

  • 自身绘制(含背景和内容)
  • 遍历子View,逐个绘制(背景和内容及装饰)
  • ViewGroup的绘制装饰
    在这里插入图片描述

自定义View的实现的步骤

步骤1:实现Measure、Layout、Draw流程

  • 从View的工作流程(measure过程、layout过程、draw过程)来看,若要实现自定义View,根据自定义View的种类不同(单一View / ViewGroup),需自定义实现不同的方法
  • 主要是onMeasure()、onLayout()、onDraw(),具体如下:
    在这里插入图片描述

自定义 Measure

ViewGroup.LayoutParams

ViewGroup 的子类(RelativeLayout、LinearLayout)有其对应的 ViewGroup.LayoutParams 子类

它的作用是指定视图View的高度和宽度等布局参数。
具体通过以下参数指定:
在这里插入图片描述
对应xml文件中:

android:layout_height="wrap_content"   //自适应大小  
android:layout_height="match_parent"   //与父视图等高  
android:layout_height="fill_parent"    //与父视图等高  
android:layout_height="100dip"         //精确设置高度值为 100dip  

MeasureSpec

MeasureSpec:策略规则,是由测量模式(mode)和测量大小(size)组成,共32位(int类型),其中mode占2位,大小占低30位。

在这里插入图片描述
测量模式分为三种:

  • UNSPECIFIED:父视图不约束子View,例如ListView、ScrollView,不过一般自定义View不用这个。
  • EXACTLY:父视图为子视图指定一个确切的尺寸,子视图大小必须是这个尺寸大小 。例如match_parent,或者指定具体的数值100dp,这种模式下,视图的测量过程会忽略视图的布局参数(LayoutParams
  • AT_MOST:父视图为子视图指定一个最大尺寸,子视图必须确保自身与所有子视图可以适应在该尺寸内。例如wrap_content,自适应大小,具体尺寸根据需求设定。这种模式下父控件无法确定子View大小,只能根据子控件自身需要设计计算尺寸。

MeasureSpec的具体使用:
MeasureSpec类用一个变量封装了测量模式(mode)和测量大小(size):通过使用二进制,将测量模式(mode)和测量大小(size)打包成一个int值,并提供了打包和解包的方法,这样的做法是为了减少对象内存分配和提高存取效率。具体使用如下所示:

// 1. 获取测量模式(Mode)
int specMode = MeasureSpec.getMode(measureSpec)

// 2. 获取测量大小(Size)
int specSize = MeasureSpec.getSize(measureSpec)

// 3. 通过Mode 和 Size 生成新的SpecMode
int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);

自定义Layout

Layout的作用是计算View的四个顶点位置:Left、Top、Right 和 Bottom

自定义属性

  1. 在values目录下创建自定义属性的xml文件
  2. 在自定义View的构造方法中加载自定义XML文件 & 解析属性值
  3. 在布局文件中使用自定义属性

绘制工具类

Paint

Paint:画笔,它的作用是确定绘制内容的具体效果(如颜色、大小等等),在绘制内容时需要画笔。

具体使用

步骤:

  1. 创建一个Paint对象
  2. 设置画笔,即绘制内容时的效果,如颜色、大小
  3. 初始化画笔(尽量选择在View的构造函数)

Path

Canvas

Canvas:画布,是一种绘制时规则,绘制内容是根据画布的规定绘制在屏幕上的。

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

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

相关文章

Python恶搞代码

文章目录 前言Tkinter界面设计Threading多线程恶搞代码 尾声 前言 快来领取python无限弹窗恶搞代码吧!每天写一些有趣的小程序,带你成为一个浪漫的程序员! Tkinter界面设计 1. 创建一个简单的界面 Tkinter 是 Python 标准库中的一个 GUI&…

自然语言处理从入门到应用——动态词向量预训练:双向语言模型

分类目录:《自然语言处理从入门到应用》总目录 对于给定的一段输入文本 w 1 w 2 ⋯ w n w_1w_2\cdots w_n w1​w2​⋯wn​,双向语言模型从前向(从左到右)和后向(从右到左)两个方向同时建立语言模型。这样做…

go 调试利器之pprof指标分析

文章目录 概要一、指标类型1.1、堆栈指标1.2、CPU指标分析1.3、http-pprof 二、go tool pprof2.1、可视化2.2、CPU火焰图 概要 Go语言原生支持对于程序运行时重要指标或特征进行分析。pprof是其中一种重要的工具,其不仅可以分析程序运行时的错误(内存泄…

ChatGPT 之 LangChain的文本切割方法对比

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! ChatGPT面向对话格式的文本理解很好,但如果要把网络上的文章让ChatGPT直接分析则会有格式的问题。文本清洗是个大课题,讲起来需要很多篇幅,优化起来前路漫…

使用arduino IDE开发ESP8266NodeMCU连接DHT11实现温湿度检测并上传onenet官网

前言: 本篇博客记录一下以arduino IDE来开发一下ESP8266NodeMCU,实现用DHT11进行温湿度检测,并且上传新版的onenet官网;我在实现这个小项目的时候,发现网上资料有关onenet的资料都是旧版的,这就有点难受了&…

[MAUI]弧形进度条与弧形滑块的交互实现

文章目录 弧形基类定义绘制弧 弧形进度条(ProgressBar)添加动画宽度补偿文本 弧形滑块(Slider)创建控制柄拖动事件处理 项目地址 进度条(ProgressBar)用于展示任务的进度,告知用户当前状态和预期; 滑块(Slider&#xf…

本地安装部署运行 ChatGLM-6B 的常见问题解答以及后续优化

报错 No module named ‘transformers_modules.THUDM/chatglm-6b’ 报错本身的意思是,没有在指定的路径THUDM/chatglm-6b找到推理用模型 一般常见于自己手动下载模型,而不是通过下边这些文件直接启动,自动下载的情况 你需要修改web_demo.py&…

分层测试终究是大梦一场空?

分层测试分了个寂寞? 分层测试这个风吹了好多年,不分层都不好意思说自己是专业测试。各互联网公司更是对此乐此不疲,测试架构、测试平台,搞了一套又一套,然而。。。 理想总是丰满,现实总是骨干&#xff0…

第十三章 反射操作相关函数

1. 【检测对象是否可被调用】callable()函数 语法参考 callable函数的语法格式如下: callable(object)参数说明: object:对象; 返回值:如果对象可调用返回 True,否则返回 False。 说明:对于…

Python 中print 和return 的区别,你了解吗?

1、print() print()函数的作用是输出数据到控制台,就是打印在你能看到的界面上。 2、return return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。 return作为脚本单独运行时则需要print函数才能显示,但是…

【id:17】【1分】A. DS顺序表--类实现

题目描述 用C语言和类实现顺序表 属性包括:数组、实际长度、最大长度(设定为1000) 操作包括:创建、插入、删除、查找 类定义参考 输入 第1行先输入n表示有n个数据,即n是实际长度;接着输入n个数据 第2行输…

c语言项目——三子棋小游戏(带详细讲解解析)

1.三子棋是什么? 三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是…

【MySQL 索引、事务与存储引擎】

目录 一、索引的介绍2、索引的作用3、创建索引的原刚依据(面试题) 二、索引的分类和创建1、普通索引2、唯一索引3、主键索引4、组合索引5、全文索引6、查看索引7、删除索引8、分析是否使用索引 三、MySQL事务介绍1、事务的ACID特性2、隔离性 --- 不一致的…

Linux编译器gcc/g++

文章目录 Liinux编译器gcc/g1.背景知识(程序的翻译)2.动态库、静态库 Liinux编译器gcc/g 1.背景知识(程序的翻译) 以gcc编译 以g编译,但是此时会发现没有g这个指令,所有需要安装它,安装指令 yum install gcc gcc-c gcc和g都会形成可执行文…

TransFusion:利用 Transformer 进行鲁棒性融合来进行 3D 目标检测

Query 初始化 Input-dependent 以往 Query 位置是随机生成或学习作为网络参数的,而与输入数据无关,因此需要额外的阶段(解码器层)来学习模型向真实对象中心移动的过程。 论文提出了一种基于center heatmap 的 input-dependent 初…

在 Python 中使用令牌进行 API 调用

文章目录 在 Python 中进行不带令牌的 API 调用在 Python 中使用令牌调用 API总结 当我们第一次遇到如何在 Python 中调用 API 的问题时,我们的第一个想法是,“什么是 API?”。 API是应用程序编程接口的首字母缩写; 它允许您访问…

【面试】Java并发编程

ThreadLocal ThreadLocal 为什么会导致内存泄漏 hreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal不存在外部强引用时,Key(ThreadLocal)势必会被GC回收,这样就会导致ThreadLocalMap中key为null, 而value还存在着…

15-ajax、实现过程、封装

定义 🍿🍿🍿Async Javascript and XML 异步的JavaScript 和XML,是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情况下,与服务器交换数据,并且更新部分网页 离不开 XMLH…

【C语言】万字教学,带你分步实现扫雷游戏(内含递归函数解析),剑指扫雷,一篇足矣

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 带你轻松玩转扫雷游戏 前言一. 扫雷游戏的介绍以及内部需要实现的功能解析1.什么是扫雷游戏2.扫雷游戏所需的几个步骤 二.扫雷游戏的具体实现1.打印菜单菜单上的选择功能 2.初始化以及打印棋盘初始化函数InitBoard打印棋…

如何使用测试驱动开发(TDD)来实现100%的测试覆盖率?

本文以 DDM 为例,简单地介绍一下如何用测试驱动开发(TDD, Test-Driven Development)的方法来驱动出这个函数库。 本文以DDM为例,简单地介绍一下如何用测试驱动开发(TDD, Test-Driven Development)的方法来驱动出这个函数库。 DDM简介 DDM是…