android 自定义控件的宽高_巧用Handler获取View控件信息

b874318f0dad4c488d9d39a62f7b1ede.png

众所周知,在Android实际开发中,对于某些复杂多变的情况,控件的位置摆放、大小控制并非是xml类型的layout文件完全可以搞定的。此时,我们通常会使用Java代码来通过动态计算,将指定的控件摆放在相应的位置,并限定其大小。同样地,也需要获取某个控件的大小。 对于获取控件宽、高的方法,大家可以自行谷歌或者百度,大抵无非一下三种方法:

  1. 给相应的View控件添加ViewTreeObserver回调
  2. Override onWindowFocusChange方法
  3. 在需要测量时(而不是onCreate或onResume中),使用MeasureSpec内部类获取宽高。

对于上述第三种情况,我们暂且不论。对于前二者而言,有没有更简单的实现呢?

为何获取宽高要如此?

对于初学者,可能会有这样的疑问:为什么我们不能在onCreate()或者onResume()中直接使用上述第三种方案获取宽高呢? 结论是:那样的话,获取来的值很可能皆为0,即使实际的宽高不是0。那么这是为何呢? 这其实是由Android的UI绘制流程决定的。大家不妨试着做一下实验,即使是在onResume()方法后,它的意义也仅仅是指Activity进入了可见的状态,这并不意味着界面绘制的结束。我们可以用一个简单的带有宽高值得View来做实验,观察Activity中各回调方法的调用顺序,得到的结果将是这样的:

Activity.oncreate() → Activity.onResume() → View.onMeasure() → View.onLayout() → onGlobalLayoutListener() → Activity.onWidnowFocusChanged() → ... → View.onDraw() -> ...

因此,如果我们在onResume()中尝试获取View宽高的话,很大概率是会失败的。

巧用Handler获取View控件信息

这里我们开门见山地先放上代码片:

private 

上述代码作为通用的方法将获取任意View的宽高做了封装,其妙处就在‘view.post’处。 将其置于onCreate()、onResume()方法中调用,均可获取到正确的宽高。

@Override

Logcat中的运行结果:

2019-01-14 22:33:13.874 18355-18355/com.example.wenhan.helloandroid I/MainActivity: Width: 225, height: 57 2019-01-14 22:33:13.874 18355-18355/com.example.wenhan.helloandroid I/MainActivity: Width: 225, height: 57

为何如此就可获取到正确的值了呢?

其中的玄机在于,我们在View.post()中所写的语句并没有立即执行,而在其真正执行的时候,View的宽高已经被测量完成了,那时我们再去获取宽高时,就会很容易地获取到正确的值了。 通过断点Debug,可以轻松地发现,在Activity启动过程的调用栈中,存在ActivityThread类被执行了,具体按照:

main() -> handleResumeActivity() -> addView() -> setView() -> requestLayout() -> scheduleTraversals() -> 执行mTraversalRunnable异步线程 -> doTraversal() -> performTraversals() -> ... -> performMeasure() -> ...

的执行顺序。 在我们获取宽高的语句执行前,主线程的Handler正在执行TraversalRunnable(见上述方法具体实现),而performMeasure也被包含其中。又因为我们获取宽高的语句要排队,处于等待状态,直到主线程Handler轮到执行我们的语句,而此时View的宽高的测量已经结束。

完整示例代码:

wh1990xiao2005/FetchViewSizeDemo​github.com
dedc9fd50c2018838313af1ce4626173.png

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

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

相关文章

ascii码01100001_ASCII码跟数字

小小乌龟把头藏: - - 我竟无言以对!举个例子嘛,本质是这样,你还是把C语言基础什么的看几遍吧。给你摘录一点书上的,估计你更能看懂:计算机是以二进制的形式来存储数据的,它只认识0和1两个数字,我…

深度linux缺点,原来国产深度系统有这些“缺陷”,难怪只有少数人在使用!

相信大家或多或少都听说过USO统一操作系统,一款可以支持多款国产芯片的国产操作系统。该系统从公布直至到现在,它一直保持着非常高的关注度。但是,有些用户认为该系统只不是Deepin换了壳而已。从系统界面来看,UOS和Deepin的确非常…

如何ping端口_干货 | 如何正确处理常见的8大网络故障

网络故障是最容易出现的,也是比较难解决的问题,尤其是经常跟电脑及交换机打交道的朋友。今天就和大家来说说日常工作中,常见的网络故障详细分析及解决方法。交换机刚加电时网络无法通信【故障现象】交换机刚刚开启的时候无法连接至其他网络&a…

前端vue显示柱状图_Vue—Echarts 柱状图

使用Vue做后台管理系统的时候避免不了使用Echarts来展示对应的数据,下面是使用Echarts柱状图来展示对应数据的实例。ee05abaf9633184a9c012631b642d970.png使用npm安装Echartsnpm install echarts --save在man.js中引入对应的echartsimport ECharts from vue-echart…

c语言程序设计第2章,C语言程序设计第2章 结构化程序设计与算法.ppt

C语言程序设计第2章 结构化程序设计与算法.ppt现在人们公认的具有“良好风格”的程序设计方法之一是所谓的“结构化程序设计方法”。其核心是规定了算法的三种基本结构顺序结构、选择结构和循环结构。按照结构化程序设计的观点,任何算法功能都可以通过三种基本程序结…

python读取word指定内容_python读取word 中指定位置的表格及表格数据

1.Word文档如下:2.代码 # -*- coding: UTF-8 -*- from docx import Document def readSpecTable(filename, specText): document Document(filename) paragraphs document.paragraphs allTables document.tables specText specText.encode(utf-8).decode(utf-8)…

xml建模包括以下_为什么要进行建模仿真?

没有“模型”作为基础的话,很多当今的前沿概念将无法真正落地!今天,数字孪生、人工智能、工业互联网、边缘计算这些概念在整个产业里非常的火热,但是,要知道,如果这些概念没有“模型”作为基础的话&#xf…

中兴没有云服务器_中国移动携手中兴通讯推进5G网络云建设

11月23日消息今年8月,中国移动通信集团公司党组成员、副总裁李慧镝在“中国信息化百人会2020年峰会”上表示,中国移动正大力推进网络云化部署,实现云网融合,NFV网络云服务器规模达6万台。2020北京国际信息通信展期间,中…

c语言乘法表只有结果,要求输出结果显示相乘的两数及乘积怎么做?

1。#includevoid main(){int i,j;printf("* ");for(i1;i10)printf("%d ",i*j);else printf("%d ",i*j);}printf("\n");}}2。#includevoid main(){int k,m,n,days;printf("请输入树的高度Kcm:");scanf("%d",&k…

差异基因 p log2foldchange_拟南芥的基因ID批量转换?差异基因,GO/KEGG数据库注释(转录组直接送你全套流程)...

新手遇到的问题都是类似的,比如批量ID转换虽然我写过大量的教程:ID转换大全 不过都需要R基础,因为是大批量转换啊!但热心肠的植物生物信息学教学大佬还是友善的给出了解决方案我也狗尾续貂制作了一个网页工具教程:简…

c语言实现顺序表源程序,C语言实现静态顺序表的实例详解

C语言实现静态顺序表的实例详解线性表定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识。只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作。接下来看看静态的顺序表&#xff0c…

证明最小码距与纠检错图像_最小码距和检错纠错能力关系

最小码距和检错纠错能力关系一、码距?码距就是两个码字C1与C2之间不同的比特数。如:1100与1010的码距为2;1111与0000的码距为4。一个编码系统的码距就是整个编码系统中任意(所有)两个码字的最小距离。若一个编码系统有四种编码分别为:0000&am…

mongoose 批量修改字段_WordPress图片路径批量替换方法

不少数站长在使用WordPress博客或者搬家时,需要把WordPress文章中的图片路径进行替换来解决图片不显示的问题。总结一下WP图片路径批量替换的过程,方便有此类需求的站长们学习。什么情况下批量替换图片路径1、更换了网站域名有许多网站建设初期都随便选择…

c语言 静态变量 初始化,c – 静态变量初始化两次

考虑到我在编译单元中有一个静态变量,最后在静态库libA中.然后我有另一个编译单元访问这个变量,最终在一个共享库libB.so(所以libA必须链接到libB).最后,我有一个主要功能也直接从A访问静态变量,并具有对libB的依赖(所以我链接到libA和libB).我然后观察,静态变量被初始化了两次…

ebs 供应商地点信息_供应商,地址,业务实体,地点关联银行账户

在此记录一下自己学习过程。新手,请多多指教,谢谢。最近客户有需求,找出供应商对应的银行信息,查看了下网上帖子,发现都是从供应商及供应商地点层发起,去查找对应的银行信息,但是,供…

c语言递归函数检测回文,递归法判断回文字符串,急用

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*--------用线性表存储字符串,结合堆栈判断回文(关键判断个数为奇或偶,奇跳过中间数据)---------*/#include #include #define ok 1;#define error 0;typedef char elemtype;typedef struct lnode{lnode *n…

python vector_50行Python代码实现经典游戏,不仅是划水神器,更是学习利器!

Free Python Games非常适合学生,它不仅具有高度的组织性和灵活性,而且能够激发人们探索和理解能力。--Terri FurtonFree Python Games在轻松的环境中把游戏和学习结合在一起,从而减轻了编程过程中的压力。--Brett Bymaster...贪吃蛇、迷宫、吃…

r roc函数_画ROC曲线的R包总结

原标题:画ROC曲线的R包总结作者: Joseph Rickert原文链接:https://rviews.rstudio.com/2019/03/01/some-r-packages-for-roc-curves/在这篇文章中,我将描述如何在CRAN中搜索绘制ROC曲线的包,并强调六个有用的包。虽然一…

c语言出圈游戏课设报告,c语言作业 出圈游戏

#include//头函数#include#include#define SIZE 100struct SeqList{int num;char name[10];};int menu_select();//函数声明部分void Joseph1();void Joseph2();void Joseph3();void Joseph4();void Joseph(struct SeqList *p,int length);void main() //主要程序段{printf(&qu…

laravel框架中文手册_node.js 后端框架star 排名 2020年11月更新,fastify 超 egg

发布时间以首个版本发布(0.x)为准。第一名: express 50.8k (2010年1月发布) 目前star 和下载量最高的老牌框架。https://github.com/expressjs/express​github.com第二名:meteor 42.1k (2012年…