Android 基础技术——View 的宽高

笔者希望做一个系列,整理 Android 基础技术,本章是关于 View 的宽高

Activity Resume 的时候设置或者获取view的宽高是否有效?

回答:不确定。 首次 onResume 无效,二次 onResume 就有效了

回顾「Android 基础技术——addView 流程」,首次 onResume 后 window&DectorView绑定, 都还没刷新,更别谈度量,谈何宽高

有什么办法在 onResume 生命周期里获取View 的宽高?

1)如果在 onResume 生命周期里 用 Handler.post 来 View.getWidth 呢??

不可以

onMeasure() 、onlayout() 也是一个 MSG,post 的时候,ui 刷新需要时间,首次 onResume 的时候都还没有刷新,所以拿不到

ViewRootImpl.scheduleTraversals 会创建消息屏障

添加消息屏障-〉执行Ui 刷新-〉消除消息屏障

消息屏障的作用:保障 ui 刷新 保障16.7ms 刷新一次

2)如果在onResume 生命周期里 用Handler.postDelay 1S 来 View.getWidth 呢??

可以

因为 Ui 刷新已经完成

3)如果用View.post

可以 

对于View.post 调用的时候

如果View已经attach到window,直接调用UI线程的Handler发送runnable。

如果View还未attach到window,将 runnable 放入 ViewRootImpl的RunQueue 中,而不是通过MessageQueue。

RunQueue的作用类似于MessageQueue,只不过这里面的所有runnable最后的执行时机,是在下一个 performTraversals 到来的时候,也就是view完成layout之后,这个时候能第一时间获取宽高,MessageQueue里的消息处理的则是下一次loop到来的时候。

换句话,View.post 的时候是一定能获取到宽高,但是 handler.post 可能还获取不到宽高。view.post 执行时候,view 层次结构已经 measure、layout 并且至少绘制完成了一次了。

获取View宽度和高度的几种方法?

1)Activity/View#onWindowFocusChanged

onWindowFocusChanged的含义:View 已经初始化完毕了,宽/高已经准备好了,这个时候获取宽/高是没有问题的。当 Activity 的当前Window获得或失去焦点时会回调此方法,也就是说当Activity暂停执行和继续执行都会回调此方法,即这个方法会被频繁调用。我们一般在第一次获取焦点时获取宽高。

2)view.post(runnable)

利用 Handler 通信机制,通过post将添加一个 Runnable到message queue的队尾,当View初始化完成之后,Looper会调用此runnable,然后通知UI线程。

3)ViewTreeObserver

当View树状态发生改变,或者View树内部的view的可见性发生改变时,onGlobalLayout会被回调,所以这也是获取宽高的一个很好的时机。伴随着View树的状态的改变,onGlobalLayout会被调用多次,因此可在第一次调用完后,移除监听事件。

4)View#addOnLayoutChangeListener

监听 View的onLayout()的绘制过程,一旦宽/高发生变化就会回调onLayoutChange方法。因此可在第一次调用完后,移除监听事件。

相关推荐

  1. android 在onCreate方法中获得view

    2024-01-22 10:12:02       32 阅读
  2. android 在 Activity onCreate 中获取View

    2024-01-22 10:12:02       21 阅读
  3. Android基础-自定义view

    2024-01-22 10:12:02       28 阅读
  4. Android基础-View与ViewGroup

    2024-01-22 10:12:02       31 阅读
  5. 新鼠标

    2024-01-22 10:12:02       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-22 10:12:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-22 10:12:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-22 10:12:02       87 阅读
  4. Python语言-面向对象

    2024-01-22 10:12:02       96 阅读

热门阅读

  1. Android问题记录

    2024-01-22 10:12:02       45 阅读
  2. ES6 速通

    2024-01-22 10:12:02       71 阅读
  3. Docker部署Golang服务

    2024-01-22 10:12:02       63 阅读
  4. 代码随想录算法训练营第二十九天|51. N皇后

    2024-01-22 10:12:02       62 阅读
  5. 为何现在流行OpenStack和Docker结合?

    2024-01-22 10:12:02       58 阅读
  6. ARM_Linux的NFS网络文件系统的搭建

    2024-01-22 10:12:02       48 阅读
  7. MySQL 8.0中引入的选项和变量(五)

    2024-01-22 10:12:02       46 阅读
  8. MySQL 简介

    2024-01-22 10:12:02       47 阅读
  9. Kafka 生产者投递内存池源码刨铣

    2024-01-22 10:12:02       51 阅读