切图做网站过时了吗,wordpress图书,电影网站怎么建设,网络笔者希望做一个系列#xff0c;整理 Android 基础技术#xff0c;本章是关于 View 的宽高 Activity Resume 的时候设置或者获取view的宽高是否有效? 回答#xff1a;不确定。 首次 onResume 无效#xff0c;二次 onResume 就有效了。 回顾「Android 基础技术——addView 流… 笔者希望做一个系列整理 Android 基础技术本章是关于 View 的宽高 Activity Resume 的时候设置或者获取view的宽高是否有效? 回答不确定。 首次 onResume 无效二次 onResume 就有效了。 回顾「Android 基础技术——addView 流程」首次 onResume 后 windowDectorView绑定 都还没刷新更别谈度量谈何宽高 有什么办法在 onResume 生命周期里获取View 的宽高 1如果在 onResume 生命周期里 用 Handler.post 来 View.getWidth 呢 不可以 onMeasure() 、onlayout() 也是一个 MSGpost 的时候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宽度和高度的几种方法 1Activity/View#onWindowFocusChanged onWindowFocusChanged的含义View 已经初始化完毕了宽/高已经准备好了这个时候获取宽/高是没有问题的。当 Activity 的当前Window获得或失去焦点时会回调此方法也就是说当Activity暂停执行和继续执行都会回调此方法即这个方法会被频繁调用。我们一般在第一次获取焦点时获取宽高。 2view.post(runnable) 利用 Handler 通信机制通过post将添加一个 Runnable到message queue的队尾当View初始化完成之后Looper会调用此runnable然后通知UI线程。 3ViewTreeObserver 当View树状态发生改变或者View树内部的view的可见性发生改变时onGlobalLayout会被回调所以这也是获取宽高的一个很好的时机。伴随着View树的状态的改变onGlobalLayout会被调用多次因此可在第一次调用完后移除监听事件。 4View#addOnLayoutChangeListener 监听 View的onLayout()的绘制过程一旦宽/高发生变化就会回调onLayoutChange方法。因此可在第一次调用完后移除监听事件。