自定义View 中很关键的问题View获取宽/高是0 的解决办法

来源:互联网 发布:java中的接口定义 编辑:程序博客网 时间:2024/06/07 10:13

原因

Activity的生命周期方法 与 View在measure过程 不是同步执行的,也就是说Activity在执行onCreate ,onStart , onResume 过程中 ,View的测量是否完成 ,得不到保证.所以 如果View没有测量完的话,View 获取的宽/高必然是0.

解决办法:

1 ViewTreeObserver

使用这个OnGlobaLayoutListener这个接口 , 视图树状态发生改变或者视图树内部的View de 可见性发升改变时, 这个接口被回调,此时 可以获得View的 宽和高.
这里写图片描述

2 view.post(runnable)

通过post 可以将一个runnable 投递到消息队列的尾部,然后等待Loop二调用到此runnable的时候, View早已经初始化完毕了.

这里写图片描述

3 onWindowFocusChanged

这个方法 , View 已经初始化完毕了.当然可以获取宽和高了.Activity 得到和失去焦点的时候这个onWindowFocusChanged ())方法均会调用一次.此时就可以获得啦.

这里写图片描述

4 view.measure(int widthMeasureSpec, int heightMeasureSpec)

手动方法对View 进行 测量来获得View的宽和高.
方法 有两种

一,指定了具体的数值
宽/高是200px
这里写图片描述

二, 在wrap_content
这里写图片描述

解释说明:MeasureSpec代表一个32位int 值, 前2位代表SpecMode(测量模式)), 后30位代表SpecSize(某种测量模式下的大小)).
所以 代码中使用了(1<<30)-1; View理论上支持的最大值.

三,在 match_parent 这中模式中 无法测量. 原因 根据源码分析 必须要知道parentSize(父类容器的剩余大小,此时我们不知道大小是多少.)

备注:根据工作经验 上面四种方法中 使用场景不同,本人常使用 第一种 和 第四种. 其他两种是通过 阅读Android相关书籍,结合自己代码 实践所得.谢谢.

2 0
原创粉丝点击