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,一经查实,立即删除!

相关文章

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

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

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北京国际信息通信展期间,中…

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

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

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

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

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

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

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年…

python音乐下载器交互界面_基于Python实现下载网易音乐代码实例

代码如下 # 爬取网易音乐 import requests from bs4 import BeautifulSoup import urllib.request headers {"origin": "https://music.163.com", "referer": "https://music.163.com/", "user-agent": "Mozilla/5.0 …

java 格式化字符串_Java入门 - 语言基础 - 14.String类

1.概述字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。2.创建字符串创建字符串最简单的方式如下:String greeting "光束云";在代码中遇到字符串常量时,这里的值是 "光束…

decimal是什么类型_SQLMysql数据类型

一 前言每个数据库的数据类型从来都不是一个简单的数据结构,特别是使用不同的数据库,不同的引擎,其支持的数据类型也不一样,选择那种数据类型作为字段类型对数据库的性能也是天差地别,故对数据类型有个全面的认知&…

mybatis依赖_Spring Boot2 系列教程(二十一)整合 MyBatis

前面两篇文章和读者聊了 Spring Boot 中最简单的数据持久化方案 JdbcTemplate,JdbcTemplate 虽然简单,但是用的并不多,因为它没有 MyBatis 方便,在 SpringSpringMVC 中整合 MyBatis 步骤还是有点复杂的,要配置多个 Bea…

android获取图片格式,Android得到图片的真实格式——从本地文件或者网络文件流...

ImageFormatFeatures支持从InputStream或者File解析四种格式:jpg 、 png 、 webp 、 gif从文件本身解析格式,而不是从扩展名获取FormatHelper.getFormat(InputStream inputStream)FormatHelper.getFormat(File file)UsageStep 1Step 2解析格式String For…

pagehelper的使用_SpringBoot项目中,如何更规范的使用PageHelper分页?

SpringBoot项目中&#xff0c;如何更规范的使用PageHelper分页&#xff0c;拉勾IT课小编为大家分解一. 开发准备1. 开发工具• IntelliJ IDEA 2020.2.32. 开发环境• Red Hat Open JDK 8u256• Apache Maven 3.6.33. 开发依赖SpringBoot<dependency><groupId>org.s…

python自动输入账号密码_Python如何基于selenium实现自动登录博客园

这篇文章主要介绍了Python如何基于selenium实现自动登录博客园,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需要做的准备&#xff1a; 本文章是使用Chrome&#xff0c;所以需要Chormedriver.exe&#xff0c;…

android 模拟长按菜单键_如何采用PLC梯形图实现单键启动程序

“PLC是一种专门为在工业环境下应用而设计的数字运算操作的电子装置。它采用可以编制程序的存储器&#xff0c;用来在其内部存储执行逻辑运算、顺序运算、计时、计数和算术运算等操作的指令&#xff0c;并能通过数字式或模拟式的输入和输出&#xff0c;控制各种类型的机械或生产…

android 日期对话框,Android日期选择器对话框DatePickerDialog使用详解

调用Android原生日期选择器对话框就是DatePickerDialog&#xff0c;具体内容如下在Android4.4系统上效果如图&#xff1a;在Android5.0以上效果如图&#xff1a;1、Activity的onCreate方法中获取当时的年&#xff0c;月&#xff0c;日Calendar ca Calendar.getInstance();mYea…

wp自定义帖子没标签_ofollow标签的作用有重大变化

nofollow标签的历史经典的nofollow标签作用和使用方法以前的帖子写过&#xff0c;详情读者可以参考以前帖子。nofollow标签&#xff08;准确说是属性&#xff0c;不过约定俗成&#xff0c;还是叫标签吧&#xff09;是Google和Yahoo等搜索引擎2005年推出的&#xff0c;目的是告诉…

android电视视频播放器,智能电视如何播放本地视频?当贝市场分享几款播放器...

原标题&#xff1a;智能电视如何播放本地视频&#xff1f;当贝市场分享几款播放器对视频清晰度要求更高的用户普遍会自己下载视频&#xff0c;然后通过本地播放的方式观影&#xff0c;那么&#xff0c;下面就给大家介绍几款智能电视的本地视频播放软件&#xff0c;包你好用。当…