Android Study Plan V
Android学习计划
话题:关于View的知识
1、View的getWidth()和getMeasuredWidth()有什么区别吗?
2、如何在onCreate中拿到View的宽度和高度?
答案
1. View的getWidth()和getMeasuredWidth()有什么区别吗?
getWidth()通过setFrame方法来决定四个顶点位置,初始化mLeft,mTop,mRight,mBottom四个参数,这四个值固定则位置确定。必须在layout过程结束才有值。
1 | |
getMeasuredWidth是在view的绘制流程中的measure结束后有值,获取的是view的测量宽高。mMeasuredWidth是在setMeasuredDimensionRaw方法中赋值的
1 | |
- 一般情况下
getMeasuredWidth和getWidth的值是相同的,从源码中可以看出setMeasuredDimensionRaw会对mMeasuredWidth进行赋值,当调用了onMeasure,会调用到setMeasuredDimensionRaw则获取的结果将会不相同
1 | |
view的绘制流程
measurelayoutdraw
measure为了计算出控件树中的各个控件要显示的内容以及大小,起点为ViewRootImpl 的 measureHierarchy ()。- SpecMode :
EXACTLY(确切大小)AT_MOST(子view的大小不得超过SpecSize)UNSPECIFIED(对子view尺寸不做限制)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/**
* Measure specification mode: The parent has not imposed any constraint
* on the child. It can be whatever size it wants.
*/
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
/**
* Measure specification mode: The parent has determined an exact size
* for the child. The child is going to be given those bounds regardless
* of how big it wants to be.
*/
public static final int EXACTLY = 1 << MODE_SHIFT;
/**
* Measure specification mode: The child can be as large as it wants up
* to the specified size.
*/
public static final int AT_MOST = 2 << MODE_SHIFT;
- SpecMode :
layout从根view开始,递归的完成控件树的布局工作,确定view的位置。先递归的对子view进行布局,在完成父布局的位置设置draw从根view开始进行绘制,利用Viwe.draw()
2.如何在onCreate中拿到View的宽度和高度?
在 Activity#onWindowFocusChanged 回调中获取宽高。
view.post(runnable),在 runnable 中获取宽高。
利用Handler通信机制,发送一个Runnable在MessageQuene中,当layout处理结束时则会发送一个消息通知UI线程,可以获取到实际宽高。ViewTreeObserver 添加 OnGlobalLayoutListener,在 onGlobalLayout 回调中获取宽高。
监听全局View的变化事件,使用后需要注意移除OnGlobalLayoutListener 监听,以免造成内存泄露调用 view.measure(),再通过 getMeasuredWidth 和 getMeasuredHeight 获取宽高。
补充知识点
- matchParent无法measure(在view的measure过程中,需要知道parentSize即父容器的剩余空间,所以无法得出measure的大小)
- [深入理解View绘制流程][1]
[1]: https://www.cnblogs.com/jycboy/p/6219915.html#autoid-7-1-0
Android Study Plan V
https://leo-wxy.github.io/2018/03/18/Android-Study-Plan-V/