当前位置: 首页 > news >正文

自定义View之重写onMeasure

一、重写onMeasure()来修改已有的View的尺寸

步骤

  1. 重写 onMeasure(),并调用 super.onMeasure() 触发原先的测量
  2. 用 getMeasuredWidth() 和 getMeasuredHeight() 取到之前测得的尺寸,利用这两个尺寸来计算出最终尺寸
  3. 使用 setMeasuredDimension() 保存尺寸

代码:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//先执行原测量算法super.onMeasure(widthMeasureSpec, heightMeasureSpec);//获取原先的测量结果int measureWidth=getMeasuredWidth();int measureHeight=getMeasuredHeight();//利用原先的测量结果计算出新的尺寸if(measureWidth>measureHeight){measureWidth=measureHeight;}else{measureHeight=measureWidth;}//保存计算后的结果setMeasuredDimension(measureWidth,measureHeight);}
​

二、重写onMeasure()来全新计算自定义View的尺寸

步骤:

  1. 重写 onMeasure0) 把尺寸计算出来
  2. 把计算的结果用 resolveSize() 过滤一遍后保存

  @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {...measuredWidth=...;measuredHeight=...;measuredWidth=resolveSize(measuredWidth,widthMeasureSpec);measuredHeight=resolveSize(measuredHeight,heightMeasureSpec);setMeasuredDimension(measuredWidth,measuredHeight);}

       onMeasure()方法的两个参数 widthMeasureSpec和heightMeasureSpec是父View对子View的尺寸限制,子View在计算自己尺寸的时候,需要遵守这两个参数所包含的限制MeasureSpec。

理解MeasureSpec

在 Android 中,View 的大小是由父容器和 View 自身的测量规格(MeasureSpec)共同决定的。

MeasureSpec 由大小和测量模式组成,测量模式有三种取值:

  1. UNSPECIFIED(未指定):父容器对子 View 没有施加任何限制,子 View 可以任意大小。

  2. EXACTLY(精确):父容器已经为子 View 精确指定了大小,子 View 应该匹配这个大小。

  3. AT_MOST(至多):子 View 可以是任何大小,但不能超过父容器指定的大小。

MeasureSpec 是通过静态方法 MeasureSpec.makeMeasureSpec() 创建的,该方法接受两个参数:大小和测量模式。在自定义 View 或者自定义布局中,我们通常会使用 MeasureSpec 来测量子 View 的大小,并根据测量模式来决定子 View 的大小。

在自定义 View 中,我们通常会在 onMeasure() 方法中使用 MeasureSpec 来测量 View 的大小。在这个方法中,我们可以通过 MeasureSpec.getMode() 和 MeasureSpec.getSize() 方法来获取测量模式和大小,然后根据这些信息来确定 View 的最终大小。

解释resolveSize()这个方法:

//代码简化,不是源码
public static int resolveSize(int size, int measureSpec) {final int specMode = MeasureSpec.getMode(measureSpec);final int specSize = MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.AT_MOST:if (specSize < size) {result = specSize | MEASURED_STATE_TOO_SMALL;} else {result = size;}break;case MeasureSpec.EXACTLY:result = specSize;break;case MeasureSpec.UNSPECIFIED:default:result = size;}
}

resolveSize()这个方法,父View传进来的尺寸限制measureSpec是由类型和尺寸值组成的,首先要调用MeasureSpec.getMode(measureSpec)方法和MeasureSpec.getSize(measureSpec)方法获取限制measureSpec的类型mode和size尺寸值。

限制的类型mode:

MeasureSpec.AT_MOST 限制上线

MeasureSpec.EXACTLY 限制固定尺寸

MeasureSpec.UNSPECIFIED 无限制

三、重写onMeasure()和onLayout()来全新计算自定义ViewGroup的内部布局

onMeasure()的重写,对于ViewGroup来说,包含三部分内容:

步骤:

  1. 调用每个子View的measure(),让子View自我测量
  2. 根据子View给出的尺寸,得出子View的位置,并保存它们的位置和尺寸
  3. 根据子View的位置和尺寸计算出自己的尺寸,并用setMeasuredDimension()保存

理解LayoutParams

       在父View里调用子View的getLayoutParams()方法,可以获得一个LayoutParams对象,它包含了xml文件里的layout_打头的参数的对应值,其中它的width和height这两个属性就分别对应了layout_width和layout_height的值,并且是转换过了的值。

    @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
​for(int i=0;i<getChildCount();i++){View childView=getChildAt(i);LayoutParams lp=childView.getLayoutParams();//lp.height   lp.width}}

结合自己的可用空间来计算出对子View的宽度和高度的限制

可以根据layout_width和layout_height的值,分成三种情况:

第一种情况:固定值

不需要考虑可用空间的问题,直接用EXACTLY把子View尺寸限制为这个固定值就可以了。

第二种情况:match_parent

把子View的尺寸限制为固定值可用宽度或者高度

可用空间的判断方法:

根据自己的MeasureSpec中mode的不同:

1.EXACTLY/AT_MOST   可用空间:MeasureSpec中的size

2.UNSPECIFIED     可用空间:无限大

第三种情况:wrap_content

不能超过父View的边界的情况下,子View自己测量

public class SomeView extends ViewGroup {
...@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {...for(int i=0;i<getChildCount();i++){View childView=getChildAt(i);LayoutParams lp=childView.getLayoutParams();int selfwidthSpecMode=MeasureSpec.getMode(widthMeasureSpec);int selfwidthSpecSize=MeasureSpec.getSize(widthMeasureSpec);switch (lp.width){case MATCH_PARENT:if(selfwidthSpecMode==EXACTLY||selfwidthSpecMode==MeasureSpec.AT_MOST){childWidthSpec=MeasureSpec.makeMeasureSpec(selfwidthSpecSize-usedWidth,EXACTLY);}else{childWidthSpec=MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);}break;case  WRAP_CONTENT:if(selfwidthSpecMode==EXACTLY||selfwidthSpecMode==MeasureSpec.AT_MOST){childWidthSpec=MeasureSpec.makeMeasureSpec(selfwidthSpecSize-usedWidth,MeasureSpec.AT_MOST);}else{childWidthSpec=MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);}break;default:childWidthSpec=MeasureSpec.makeMeasureSpec(lp.width, EXACTLY);break;}}}
}

关于保存子View位置的两点说明

1.不是所有的Layout都需要保存子View的位置(因为有的Layout可以在布局阶段实时推导出子View的位置,例如LinearLayout)

2.有时候对某些子View需要重复测量两次或多次才能得到正确的尺寸和位置

重写onLayout()来摆放子View

    @Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {for(int i=0;i<getChildCount();i++){View childView=getChildAt(i);childView.layout(childLeft[i],childTop[i],childRight[i],childBottom[i]);}}

 

相关文章:

自定义View之重写onMeasure

一、重写onMeasure()来修改已有的View的尺寸 步骤&#xff1a; 重写 onMeasure()&#xff0c;并调用 super.onMeasure() 触发原先的测量用 getMeasuredWidth() 和 getMeasuredHeight() 取到之前测得的尺寸&#xff0c;利用这两个尺寸来计算出最终尺寸使用 setMeasuredDimensio…...

专为Mac用户设计的思维导图软件MindNode 2023 for Mac助您激发创意!

在现代快节奏的生活中&#xff0c;我们经常需要整理思绪、规划项目、记录灵感。而思维导图作为一种高效的思维工具&#xff0c;能够帮助我们更好地整理和展现思维。现在&#xff0c;我们介绍一款强大而直观的思维导图软件——MindNode 2023 for Mac&#xff0c;助您拓展思维边界…...

Linux命令——用户和权限相关

文章目录 1 用户管理1.1 用户标识符1.2 用户添加1.3 用户删除1.4 用户配置文件1.4.1 passwd文件1.4.2 shadow文件1.4.3 group文件 2 密码管理3 权限管理 1 用户管理 1.1 用户标识符 用户标识符主要是UID和GID&#xff0c;UID表示用户id&#xff0c;GID表示用户组id。在登录的…...

linux反汇编工具: ida pro、rizinorg/cutter; ubuntu 22 flameshot延迟截图 以应对下拉菜单

rizinorg/cutter rizinorg/cutter 是 命令行反汇编工具 rizinorg/rizin 的图形化界面, 这比 ida pro跑在kvm虚拟机中方便多了, ubuntu22.04下直接下载Cutter-v2.3.2-Linux-x86_64.AppImage后即可运行,如下图: 注意 有个同名的报废品: radare2/Cutter 即 radare2的图形化界…...

【INTEL(ALTERA)】使用NiosV/m 处理器,niosv-download 为什么会失败?

说明 在英特尔 Quartus Prime Pro Edition 软件 23.3 版及更高版本中将 Nios V 处理器软件下载到非流水线Nios V/m 处理器时&#xff0c;可能会出现此问题。 这是由于处理器限制&#xff0c;仅影响非流水线Nios V/m 处理器。 以下其他处理器不受此限制的影响&#xff1a; 管道…...

【无线通信专题】NFC通信模式及可能的应用方式

在文章【无线通信专题】NFC基本原理中我们讲到了NFC工作模式。其中NFC工作模式主要有三种,读写模式、卡模拟模式、点对点模式。 NFC通信模式丰富,NFC Forum定义了三种NFC设备:通用NFCForum设备、读写器设备和标签设备。这些NFC设备可以在三种通信模式下运行,并对应用案例进…...

pyinstaller生成的exe文件启动时间漫长的原因

加-F慢的原因是&#xff0c;pyinstaller把所有资源文件包括python解释器的依赖文件和库都打包到exe一个文件中&#xff0c;用户打开时&#xff0c;pyinstaller需要先执行一边解压操作&#xff0c;把依赖文件全部解压出来。慢就慢在这里。 如果不加-F&#xff0c;你会发现那些文…...

C语言基本语句介绍

c程序的执行部分是由语句组成的。程序的功能也是由执行语句来实现的&#xff0c;c语句分为6类 1表达式语句 表达式语句由表达式加上分号“&#xff1b;”组成 一般形式&#xff1a;表达式&#xff1b; 2函数调用语句 由函数名&#xff0c;实际参数加上分号“&#xff1b;”…...

【QT】QString类型中,Empty和NULL有什么区别在qt里,对比C#

在 Qt 中&#xff0c;QString 类型的字符串使用 isEmpty() 方法来检查字符串是否为空&#xff0c;而不是使用 null。这与 C# 中的 string.IsNullOrEmpty 方法略有不同。 QString::isEmpty()&#xff1a; 用于检查字符串是否为空。一个 QString 对象可能是空字符串&#xff0c;即…...

破壳而出:运维工程师在新科技热潮下的崛起与转型

运维工程师的出路到底在哪里&#xff1f; 在这个飞速发展的数字世界里&#xff0c;运维工程师无疑是IT界冲在最前线的勇士。他们曾是服务器的守护者&#xff0c;他们曾是故障的消灭者&#xff0c;他们曾是性能的推手。然而&#xff0c;随着科技的发展和市场需求的变化&#xf…...

静态网页设计——贵州美食(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1vC4y1K7de/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…...

imgaug库指南(六):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…...

stable diffusion 人物高级提示词(五)场景、特效、拍摄手法、风格

一、场景 场景Promptindoor室内outdoor室外cityscape城市景色countryside乡村beach海滩forest森林mountain山脉snowfield雪原skyscraper摩天大楼ancient monument古代遗迹cathedral大教堂library图书馆museum博物馆office building办公大楼restaurant餐厅street market街头市场…...

智能分析网关V4智慧港口码头可视化视频智能监管方案

一、需求背景 近年来&#xff0c;水利港口码头正在进行智能化建设&#xff0c;现场管理已经是重中之重。港口作为货物、集装箱堆放及中转机构&#xff0c;具有昼夜不歇、天气多变、环境恶劣等特性&#xff0c;安全保卫工作显得更加重要。港口码头的巡检现场如何高效、快捷地对…...

docker部署kibana

1&#xff0c;简介 官网 kibana 2&#xff0c;安装docker 参考 linux安装docker 3&#xff0c;准备 Kibana 配置文件 # 进入主节点配置文件目录 cd /export/server/docker/kibana/config # 编辑单机版配置文件 vi kibana.ymlkibana.yml内容 # 主机地址&#xff0c;可以是…...

【AI视野·今日CV 计算机视觉论文速览 第283期】Thu, 4 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Thu, 4 Jan 2024 Totally 85 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers LEAP-VO: Long-term Effective Any Point Tracking for Visual Odometry Authors Weirong Chen, Le Chen, Rui Wang, Marc P…...

sort实现自定义排序方法详解

使用 sort 实现自定义排序 目录 使用 sort 实现自定义排序1.sort 的基本用法2.sort 实现自定义排序3.结构体重载进行比较 1.sort 的基本用法 sort 库函数需要引入头文件algorithm,是一种排序算法&#xff0c;使用的排序逻辑可以看成是效率很高的快速排序或其的改进版本。平均时…...

【攻防世界】Reverse——secret-galaxy-300 writeup

由main函数查看相关代码&#xff0c;但是代码中并没有直接的关于flag的信息&#xff1a; int __cdecl main(int argc, const char **argv, const char **envp) {__main();fill_starbase(&starbase);print_starbase((int)&starbase);return 0; } void __cdecl fill_sta…...

Github Copilot 快速入门

GitHub Copilot 是一个由 GitHub 推出的人工智能编程助手&#xff0c;旨在帮助开发者通过自动代码建议和补全来提高编程效率和质量。作为一个人工智能配对程序员&#xff0c;它能够理解你的代码意图&#xff0c;并提供相关的代码片段&#xff0c;以帮助你更快地编写代码。这种技…...

c# wpf 的触发器,触发器Trigger种类,每个触发器的使用说明

触发器是一种强大的声明性机制&#xff0c;用于根据指定条件更改控件的外观或行为。触发器主要分为以下几种类型&#xff1a; Property Trigger 说明&#xff1a;当绑定到控件某个依赖属性的值发生改变时&#xff0c;Property Trigger会执行预定义的一组设置。例如&#xff0c;…...

计算机毕业设计 SpringBoot的乡村养老服务管理系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

AMP 通讯RPMsg

参考 RPMsg&#xff1a;协议简介_rpmsg协议-CSDN博客 【软件架构】【通信】S32G IPCF - 知乎 openamp https://www.cnblogs.com/sky-heaven/p/14085800.html virtualIO 虚拟化技术 — VirtIO 虚拟设备接口标准 - 知乎 Virtio-fs介绍与性能优化_guest docker Docker Docs 扫…...

【ECMAScript】WebSocket模拟HTTP功能的实践:Promise+WebSocket+EventEmitter+Queue

1. 前言 本篇将结合Promise、WebSocket、EventEmitter和Queue&#xff0c;做一次实践&#xff1a;用WebSocket来模拟HTTP的功能。先不用关心它的用处&#xff0c;就当一次对知识点的整合吧。 2. MockHTTP 方法说明request(params, callback?) 功能&#xff1a;发起请求&…...

Linux 软raid - - Barrier

什么是Barriers 在linux软raid中&#xff0c;用来处理正常IO和同步IO的并发问题&#xff0c;可以简单理解为专用于软raid的锁。 软raid在做resync/recovery&#xff0c;或者配置操作时需要raise 屏障&#xff0c;于此同时必须暂停正常IO。 barrier是可以被多次raise的一个计数…...

航空公司管理系统(迷你版12306)

要求 今天分享一个之前辅导留学生的作业&#xff0c;作业要求如下&#xff1a; Project E: Airways Management System Overall description: Your team is employed by an Airways company for the implementation of a computer system responsible for a large part of th…...

嵌入式硬件电路原理图之跟随电路

描述 电压跟随电路 电压跟随器是共集电极电路&#xff0c;信号从基极输入&#xff0c;射极输出&#xff0c;故又称射极输出器。基极电压与集电极电压相位相同&#xff0c;即输入电压与输出电压同相。这一电路的主要特点是&#xff1a;高输入电阻、低输出电阻、电压增益近似为…...

学习录

概述 这几年在迷茫中看了不少资料&#xff0c;有觉得写得很棒的&#xff0c;也有写的很糟糕的。所以一直想写这块的总结来进行归纳&#xff0c;同时也希望能给其他处于迷茫中的朋友提供一份高质量的资料列表(也许一个读者也没有)&#xff0c;以下清单个人觉得值得反复看以及思…...

MongoDB索引详解

概述 索引是一种用来快速查询数据的数据结构。BTree 就是一种常用的数据库索引数据结构&#xff0c;MongoDB 采用 BTree 做索引&#xff0c;索引创建 colletions 上。MongoDB 不使用索引的查询&#xff0c;先扫描所有的文档&#xff0c;再匹配符合条件的文档。使用索引的查询&…...

一文搞定JVM内存模型

鲁大猿&#xff0c;寻精品资料&#xff0c;帮你构建Java全栈知识体系 www.jiagoujishu.cn 运行时数据区 内存是非常重要的系统资源&#xff0c;是硬盘和 CPU 的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM 内存布局规定了 Java 在运行过程中内存申请、…...

月报总结|Moonbeam 12月份大事一览

一转眼已经到年底啦。本月&#xff0c;Moonbeam基金会发布四个最新战略重点&#xff1a;跨链解决方案、游戏、真实世界资产&#xff08;RWA&#xff09;、新兴市场。其中在新兴市场方面&#xff0c;紧锣密鼓地推出与巴西公司Grupo RO的战略合作。 用户教育方面&#xff0c;为了…...

公司网站做一下多少钱/b2b平台都有哪些网站

所以说&#xff0c;这写程序啊&#xff0c;一个月不写就手生。在运行 Java 程序时经常要指定一个包含各种 jar 包的目录作为类路径&#xff0c;以前我们习惯用 -Djava.ext.dirs... 来指定这个 jar 目录。但在新版的 JDK 中&#xff0c;好像是从 JDK 9 开始&#xff0c;当你还用…...

郑州网约车资格证/seo概念的理解

一、风险管理的主要过程 软件项目中的风险是指软件开发过程中及软件产品本身可能造成的伤害或损失&#xff0c;风险管理的目的是在问题出现之前就识别出潜在的问题&#xff0c;以便风险处理活动可以得到计划&#xff0c;并在产品或项目整个生命周期中根据需要调用&#xff0c;…...

免费游戏网站制作/推广普通话的意义50字

2019独角兽企业重金招聘Python工程师标准>>> 下载&#xff1a; http://v3.bootcss.com/getting-started/#examples 可以下载用于 生产环境的 Bootstrap 使用步骤&#xff1a; 需要引入三个文件&#xff1a; bootstrap.min.css jquery-1.11.3.min.js bootstrap.…...

做外贸的社交网站/下拉关键词排名

微博被定义为社交媒体&#xff0c;微信朋友圈被定义为社交网络&#xff0c;从两者的区别注定了微博的媒体属性&#xff0c;当他的流量不行的时候&#xff0c;主它是八卦小报也不为过。如果没有微信朋友圈的崛起&#xff0c;可能今天的微博影响力会大得多&#xff0c;可能也就不…...

vpsputty做网站/北京网站推广营销策划

原本以为这个委托需要两个参数&#xff0c;汗&#xff0c;现在总算是弄清楚正确了&#xff0c;Func<T,TResult>是一个只需要一个参数的委托&#xff0c;其参数类型为T&#xff0c;返回值类型会TResult... 用Lambda写的形式是&#xff1a;&#xff08;T类型对象的参数&am…...

wordpress注册时添密码/如何制作网页链接

转载自&#xff1a;AnnotationConfigApplicationContext_Kwqin的博客-CSDN博客...