博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 获得View宽高的几种方式
阅读量:6822 次
发布时间:2019-06-26

本文共 2644 字,大约阅读时间需要 8 分钟。

《Android开发艺术探索》笔记:

在Activity的onCreate()或者onResume()中去获得View的高度的时候不能正确获得宽度和高度信息,这是因为 View的measure过程和Activity的生命周期不是同步执行的,因此无法保证Activity执行了onCreate onStart onResume时,某个View已经测量完毕了,如果还没有测量完,那么获得的宽高就是0。可以通过下面几种方式来获得:

#####1、onWindowFocusChanged

onWindowFocusChanged:View已经初始化完毕,宽高已经有了,需要注意onWindowFocusChanged会被调用多次,Activity得到焦点和失去焦点都会执行这个回调,见下图:

1、Activity首次进入的时候执行的方法 2、跳转到另一个Activity时 3、返回到当前Activity时 可见当执行onResume和onPause时,onWindowFocusChanged都会被调用。

@Override public void onWindowFocusChanged(boolean hasFocus) {     super.onWindowFocusChanged(hasFocus);     if (hasFocus) {         //获得宽度         int width = view.getMeasuredWidth();         //获得高度         int height = view.getMeasuredHeight();     } }复制代码

#####2、view.post(runnable) 通过post可以将一个runnable投递到消息队列的尾部,等待Looper调用此runnable的时候,View也已经初始化好了,示例:

@Override protected void onStart() {     super.onStart();     view.post(new Runnable() {         @Override         public void run() {             int width=view.getMeasuredWidth();             int height=view.getMeasuredHeight();         }     }) }复制代码

#####3、ViewTreeObserver 使用ViewTreeObserver的众多回调可以完成这个功能,比如使用OnGlobalLayoutListener这个接口,当View树的状态发生改变或者View树内部的View的可见性发生改变时,OnGlobalLayout方法将会被回调,这是获取View宽高很好的一个时机,需要注意的是,伴随着View树的状态改变,OnGlobalLayout会被调用多次,示例:

@Overrideprotected void onStart() {    super.onStart();    ViewTreeObserver observer=view.getViewTreeObserver();    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {        @Override        public void onGlobalLayout() {            view.getViewTreeObserver().removeOnGlobalLayoutListener(this);            int width=view.getMeasuredWidth();            int height=view.getMeasuredHeight();        }    });}复制代码

更详细参看:

4、view.measure(int widthMeasureSpec, int heightMeasureSpec)

通过手动对View进行measure来得到View的宽高,这里要分情况处理,根据View的LayoutParams来分:

  • match-parent 无法测出具体的宽高,因为根据View的measure过程,构造此种MeasureSpec需要知道parentSize,即父容器的剩余空间,而这个值我们是不知道的,所以不能测出View的大小。

  • 具体的数值(dp/px) 比如宽高都是100px,如下measure:

int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY); int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec);复制代码
  • wrap_content

如下measure:

int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST); int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST); view.measure(widthMeasureSpec, heightMeasureSpec);复制代码

View的specSize使用30位二进制表示,也就是说最大是30个1,也就是(1 << 30) - 1,在最大化模式下,我们用View理论上能支持的最大值去构造MeasureSpec是合理的。

转载于:https://juejin.im/post/5a33e7b051882506146ef9ba

你可能感兴趣的文章
mysql-5.6.26 主主复制
查看>>
SpringMVC权限管理
查看>>
ET120以太网环回器介绍
查看>>
ActiveMQ快速入门
查看>>
java自学篇之程序设计基础
查看>>
swiper的基础使用(五)
查看>>
Windows Server 2012R2 Hyper-v之虚拟机复制(2)
查看>>
大数据各种实用网站
查看>>
win7安装laravel
查看>>
Oracle 各后台进程功能说明
查看>>
屏蔽storm ui的kill功能
查看>>
我的友情链接
查看>>
Oracle Decode函数的使用
查看>>
MSF学习笔记
查看>>
经典脚本案例--check memory
查看>>
20.31 expect脚本同步文件;20.32 expect脚本指定host和要同步的文件;20.33 构建文件分发系统;20.34...
查看>>
CentOS单用户与救援模式
查看>>
postfix 源码centos7上搭建及错误提示---亲测
查看>>
【Redis篇】Redis集群安装与初始
查看>>
jquery基础
查看>>