Android应用篇 - 从不同场景来理解 View 的绘制流程
很多文章都讲解了 View 的绘制流程,今天我想换种方式,用例子来理解。
目录:
- 准备工作
- 单个 View 测试
- ViewGroup + View 测试
1. 准备工作
准备两个自定义 View,分别重写 TextView 和 LinearLayout:
public class MyTextView extends TextView {
public MyTextView(Context context) {
super(context);
Log.i(Constants.TAG, "MyTextView constructor0");
}
public MyTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Log.i(Constants.TAG, "MyTextView constructor1");
}
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.i(Constants.TAG, "MyTextView constructor2");
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
Log.i(Constants.TAG, "MyTextView onLayout:" + " changed = " + changed + " ,left = " + l + " ,top = " + t +
" ,right = " + r + " ,bottom = " + b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.i(Constants.TAG, "MyTextView onMeasure:" + " widthMeasureSpec = " + widthMeasureSpec
+ " ,heightMeasureSpec = " + heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i(Constants.TAG, "MyTextView onDraw");
}
}
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
Log.i(Constants.TAG, "MyLinearLayout constructor0");
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Log.i(Constants.TAG, "MyLinearLayout constructor1");
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.i(Constants.TAG, "MyLinearLayout constructor2");
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i(Constants.TAG, "MyLinearLayout onLayout start:" + " changed = " + changed + " ,left = " + l + " ,top = " + t +
" ,right = " + r + " ,bottom = " + b);
super.onLayout(changed, l, t, r, b);
Log.i(Constants.TAG, "MyLinearLayout onLayout end:" + " changed = " + changed + " ,left = " + l + " ,top = " + t +
" ,right = " + r + " ,bottom = " + b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i(Constants.TAG, "MyLinearLayout onMeasure start:" + " widthMeasureSpec = " + widthMeasureSpec
+ " ,heightMeasureSpec = " + heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.i(Constants.TAG, "MyLinearLayout onMeasure end:" + " widthMeasureSpec = " + widthMeasureSpec
+ " ,heightMeasureSpec = " + heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
Log.i(Constants.TAG, "MyLinearLayout onDraw start");
super.onDraw(canvas);
Log.i(Constants.TAG, "MyLinearLayout onDraw end");
}
@Override
protected void dispatchDraw(Canvas canvas) {
Log.i(Constants.TAG, "MyLinearLayout dispatchDraw start");
super.dispatchDraw(canvas);
Log.i(Constants.TAG, "MyLinearLayout dispatchDraw end");
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
Log.i(Constants.TAG, "MyLinearLayout drawChild start");
boolean b = super.drawChild(canvas, child, drawingTime);
Log.i(Constants.TAG, "MyLinearLayout drawChild end");
return b;
}
}
2. 单个 View 测试
- 2.1 布局文件
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<io.kzw.androidview.MyTextView
android:id="@+id/text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/visible_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="visible"/>
<Button
android:id="@+id/invisible_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="invisible"/>
<Button
android:id="@+id/gone_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="gone"/>
<Button
android:id="@+id/adjust_size_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="adjust size"/>
<Button
android:id="@+id/change_text_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="change text"/>
<Button
android:id="@+id/request_layout_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="request layout"/>
<Button
android:id="@+id/invalidate_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="invalidate"/>
<Button
android:id="@+id/post_invalidate_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="post_invalidate"/>
</LinearLayout>
从布局中可以看到,我们测试的内容主要是对 TextView 做如下操作:
setVisibility(View.VISIBLE)
setVisibility(View.INVISIBLE)
setVisibility(View.GONE)
layoutParams.width = 300
setText()
requestLayout()
invalidate()
postInvalidate()
- 2.2 测试结果
03-14 16:27:19.357 20645 20645 I TestView: MyTextView constructor1
03-14 16:27:19.514 20645 20645 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482570 ,heightMeasureSpec = -2147482232
03-14 16:27:19.555 20645 20645 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 16:27:19.557 20645 20645 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 16:27:32.089 20645 20645 I TestView: MyTextView onDraw
03-14 16:27:42.327 20645 20645 I TestView: set INVISIBLE
03-14 16:27:45.754 20645 20645 I TestView: set VISIBLE
03-14 16:27:45.766 20645 20645 I TestView: MyTextView onDraw
03-14 16:27:51.492 20645 20645 I TestView: set GONE
03-14 16:27:53.238 20645 20645 I TestView: set VISIBLE
03-14 16:27:53.243 20645 20645 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 16:27:53.245 20645 20645 I TestView: MyTextView onLayout: changed = false ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 16:27:53.251 20645 20645 I TestView: MyTextView onDraw
03-14 16:27:56.644 20645 20645 I TestView: adjustSize
03-14 16:28:00.282 20645 20645 I TestView: setText
03-14 16:28:00.291 20645 20645 I TestView: MyTextView onDraw
03-14 16:28:04.229 20645 20645 I TestView: requestLayout
03-14 16:28:04.235 20645 20645 I TestView: MyTextView onMeasure: widthMeasureSpec = 1073742124 ,heightMeasureSpec = -2147482056
03-14 16:28:04.239 20645 20645 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 300 ,bottom = 53
03-14 16:28:04.241 20645 20645 I TestView: MyTextView onDraw
03-14 16:28:06.866 20645 20645 I TestView: invalidate
03-14 16:28:06.876 20645 20645 I TestView: MyTextView onDraw
03-14 16:28:08.352 20645 20645 I TestView: postInvalidate
03-14 16:28:08.366 20645 20645 I TestView: MyTextView onDraw
- (1) 初始化状态:
- (2) setVisibility(View.INVISIBLE) -> setVisibility(View.VISIBLE) -> setVisibility(View.GONE) -> setVisibility(View.VISIBLE):
可以看出,从可见到不可见,都没有回调,但是从不可见到可见都会回调 onDraw(),只不过从 GONE 到 VISIBLE 会重新回调 onMeasure() 和 onLayout()。
- (3) 重置宽高
无任何回调。
- (4) setText()
回调 onDraw()。
- (5) requestLayout()
回调 onMeasure() -> onLayout() -> onDraw()。
- (6) invalidate() | postInvalidate()
回调 onDraw()。
3. ViewGroup + View 测试
- 3.1 布局文件
<io.kzw.androidview.MyLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<io.kzw.androidview.MyTextView
android:id="@+id/text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</io.kzw.androidview.MyLinearLayout>
在 TextView 外层包一个父容器。
- 3.2 只变化 TextView
03-14 17:29:28.352 26138 26138 I TestView: MyLinearLayout constructor1
03-14 17:29:28.356 26138 26138 I TestView: MyTextView constructor1
03-14 17:29:28.450 26138 26138 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742902 ,heightMeasureSpec = -2147482232
03-14 17:29:28.451 26138 26138 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482570 ,heightMeasureSpec = -2147482232
03-14 17:29:28.452 26138 26138 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742902 ,heightMeasureSpec = -2147482232
03-14 17:29:28.467 26138 26138 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:28.468 26138 26138 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 17:29:28.468 26138 26138 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:28.470 26138 26138 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 17:29:28.471 26138 26138 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 17:29:28.471 26138 26138 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 17:29:28.489 26138 26138 I TestView: MyLinearLayout dispatchDraw start
03-14 17:29:28.489 26138 26138 I TestView: MyLinearLayout drawChild start
03-14 17:29:28.489 26138 26138 I TestView: MyTextView onDraw
03-14 17:29:28.489 26138 26138 I TestView: MyLinearLayout drawChild end
03-14 17:29:28.489 26138 26138 I TestView: MyLinearLayout dispatchDraw end
03-14 17:29:32.026 26138 26138 I TestView: set INVISIBLE
03-14 17:29:32.045 26138 26138 I TestView: MyLinearLayout dispatchDraw start
03-14 17:29:32.045 26138 26138 I TestView: MyLinearLayout dispatchDraw end
03-14 17:29:40.658 26138 26138 I TestView: set VISIBLE
03-14 17:29:40.668 26138 26138 I TestView: MyLinearLayout dispatchDraw start
03-14 17:29:40.668 26138 26138 I TestView: MyLinearLayout drawChild start
03-14 17:29:40.669 26138 26138 I TestView: MyTextView onDraw
03-14 17:29:40.669 26138 26138 I TestView: MyLinearLayout drawChild end
03-14 17:29:40.669 26138 26138 I TestView: MyLinearLayout dispatchDraw end
03-14 17:29:46.415 26138 26138 I TestView: set GONE
03-14 17:29:46.422 26138 26138 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:46.422 26138 26138 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:46.432 26138 26138 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 0
03-14 17:29:46.432 26138 26138 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 0
03-14 17:29:46.452 26138 26138 I TestView: MyLinearLayout dispatchDraw start
03-14 17:29:46.452 26138 26138 I TestView: MyLinearLayout dispatchDraw end
03-14 17:29:48.538 26138 26138 I TestView: set VISIBLE
03-14 17:29:48.546 26138 26138 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:48.546 26138 26138 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 17:29:48.547 26138 26138 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:48.551 26138 26138 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 17:29:48.551 26138 26138 I TestView: MyTextView onLayout: changed = false ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 17:29:48.551 26138 26138 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 17:29:48.561 26138 26138 I TestView: MyLinearLayout dispatchDraw start
03-14 17:29:48.561 26138 26138 I TestView: MyLinearLayout drawChild start
03-14 17:29:48.562 26138 26138 I TestView: MyTextView onDraw
03-14 17:29:48.562 26138 26138 I TestView: MyLinearLayout drawChild end
03-14 17:29:48.562 26138 26138 I TestView: MyLinearLayout dispatchDraw end
03-14 17:29:51.325 26138 26138 I TestView: adjustSize
03-14 17:29:55.185 26138 26138 I TestView: setText
03-14 17:29:55.192 26138 26138 I TestView: MyTextView onDraw
03-14 17:29:58.401 26138 26138 I TestView: requestLayout
03-14 17:29:58.408 26138 26138 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:58.409 26138 26138 I TestView: MyTextView onMeasure: widthMeasureSpec = 1073742124 ,heightMeasureSpec = -2147482056
03-14 17:29:58.409 26138 26138 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 17:29:58.411 26138 26138 I TestView: MyLinearLayout onLayout start: changed = false ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 17:29:58.412 26138 26138 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 300 ,bottom = 53
03-14 17:29:58.412 26138 26138 I TestView: MyLinearLayout onLayout end: changed = false ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 17:29:58.414 26138 26138 I TestView: MyLinearLayout dispatchDraw start
03-14 17:29:58.414 26138 26138 I TestView: MyLinearLayout drawChild start
03-14 17:29:58.415 26138 26138 I TestView: MyTextView onDraw
03-14 17:29:58.415 26138 26138 I TestView: MyLinearLayout drawChild end
03-14 17:29:58.415 26138 26138 I TestView: MyLinearLayout dispatchDraw end
03-14 17:30:02.589 26138 26138 I TestView: invalidate
03-14 17:30:02.599 26138 26138 I TestView: MyTextView onDraw
03-14 17:30:04.953 26138 26138 I TestView: postInvalidate
03-14 17:30:04.969 26138 26138 I TestView: MyTextView onDraw
- (1) 初始化状态
- (2) setVisibility(View.INVISIBLE) -> setVisibility(View.VISIBLE) -> setVisibility(View.GONE) -> setVisibility(View.VISIBLE):
由可见到不可见,都会回调 MyLinearLayout 的 dispatchDraw(),MyTextView 无任何回调,区别在于 GONE 时 MyLinearLayout 会重新执行 onMeasure() 和 onLayout()。 从不可见到可见,MyLinearLayout 和 MyTextView 都会走一次 draw() 的流程,区别在于从 GONE 到可见,会重新走一次 MyLinearLayout 和 MyTextView 的 measure、layout 流程。
补充一点,没有看到 MyLinearLayout 的 onDraw() 回调啊?
ViewGroup 默认情况下,会被设置成 WILL_NOT_DRAW,这是从性能考虑,这样一来,onDraw() 就不会被调用了。
如果希望 onDraw() 回调,有两种方法:
- 给 ViewGroup 设置一个背景。
- 在构造函数里面,调用 setWillNotDraw(false),去掉其 WILL_NOT_DRAW flag。
比如上面给 MyLinearLayout 在布局中设置背景,看看上述场景的打印回调:
03-14 18:27:02.580 28063 28063 I TestView: MyLinearLayout constructor1
03-14 18:27:02.583 28063 28063 I TestView: MyTextView constructor1
03-14 18:27:02.685 28063 28063 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742902 ,heightMeasureSpec = -2147482232
03-14 18:27:02.687 28063 28063 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482570 ,heightMeasureSpec = -2147482232
03-14 18:27:02.687 28063 28063 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742902 ,heightMeasureSpec = -2147482232
03-14 18:27:02.720 28063 28063 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:27:02.720 28063 28063 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 18:27:02.720 28063 28063 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:27:02.722 28063 28063 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:27:02.722 28063 28063 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 18:27:02.722 28063 28063 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:27:02.739 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:27:02.739 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:27:02.739 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:27:02.739 28063 28063 I TestView: MyLinearLayout drawChild start
03-14 18:27:02.740 28063 28063 I TestView: MyTextView onDraw
03-14 18:27:02.740 28063 28063 I TestView: MyLinearLayout drawChild end
03-14 18:27:02.740 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:27:06.697 28063 28063 I TestView: set INVISIBLE
03-14 18:27:06.707 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:27:06.707 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:27:06.707 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:27:06.707 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:27:28.553 28063 28063 I TestView: set VISIBLE
03-14 18:27:28.560 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:27:28.560 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:27:28.560 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:27:28.560 28063 28063 I TestView: MyLinearLayout drawChild start
03-14 18:27:28.561 28063 28063 I TestView: MyTextView onDraw
03-14 18:27:28.561 28063 28063 I TestView: MyLinearLayout drawChild end
03-14 18:27:28.561 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:27:41.052 28063 28063 I TestView: set GONE
03-14 18:27:41.065 28063 28063 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:27:41.066 28063 28063 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:27:41.072 28063 28063 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 0
03-14 18:27:41.072 28063 28063 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 0
03-14 18:27:41.088 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:27:41.088 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:27:41.088 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:27:41.088 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:27:54.257 28063 28063 I TestView: set VISIBLE
03-14 18:27:54.266 28063 28063 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:27:54.266 28063 28063 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 18:27:54.266 28063 28063 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:27:54.269 28063 28063 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:27:54.269 28063 28063 I TestView: MyTextView onLayout: changed = false ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 18:27:54.270 28063 28063 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:27:54.275 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:27:54.275 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:27:54.275 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:27:54.275 28063 28063 I TestView: MyLinearLayout drawChild start
03-14 18:27:54.275 28063 28063 I TestView: MyTextView onDraw
03-14 18:27:54.276 28063 28063 I TestView: MyLinearLayout drawChild end
03-14 18:27:54.276 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:27:57.467 28063 28063 I TestView: adjustSize
03-14 18:28:01.910 28063 28063 I TestView: setText
03-14 18:28:01.921 28063 28063 I TestView: MyTextView onDraw
03-14 18:28:05.057 28063 28063 I TestView: requestLayout
03-14 18:28:05.062 28063 28063 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:28:05.062 28063 28063 I TestView: MyTextView onMeasure: widthMeasureSpec = 1073742124 ,heightMeasureSpec = -2147482056
03-14 18:28:05.062 28063 28063 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:28:05.065 28063 28063 I TestView: MyLinearLayout onLayout start: changed = false ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:28:05.065 28063 28063 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 300 ,bottom = 53
03-14 18:28:05.066 28063 28063 I TestView: MyLinearLayout onLayout end: changed = false ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:28:05.068 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:28:05.068 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:28:05.068 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:28:05.068 28063 28063 I TestView: MyLinearLayout drawChild start
03-14 18:28:05.069 28063 28063 I TestView: MyTextView onDraw
03-14 18:28:05.069 28063 28063 I TestView: MyLinearLayout drawChild end
03-14 18:28:05.069 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:28:08.560 28063 28063 I TestView: invalidate
03-14 18:28:08.566 28063 28063 I TestView: MyTextView onDraw
03-14 18:28:10.615 28063 28063 I TestView: postInvalidate
03-14 18:28:10.636 28063 28063 I TestView: MyTextView onDraw
可以看到,MyLinearLayout 在所有会调用 dispatchDraw() 的场景之前都会调用 onDraw()。
- (3) 调整宽高
无任何回调。
- (4) setText()
MyTextView 回调 onDraw()。
- (5) requestLayout()
MyLinearLayout 和 MyTextView 重走一遍 measure(),layout() 和 draw() 流程。
- (6) invalidate() | postInvalidate()
MyTextView 回调 onDraw()。
- 3.3 只变化 LinearLayout
03-14 18:40:18.954 28063 28063 I TestView: MyLinearLayout onDraw start
03-14 18:40:18.954 28063 28063 I TestView: MyLinearLayout onDraw end
03-14 18:40:18.954 28063 28063 I TestView: MyLinearLayout dispatchDraw start
03-14 18:40:18.954 28063 28063 I TestView: MyLinearLayout drawChild start
03-14 18:40:18.954 28063 28063 I TestView: MyTextView onDraw
03-14 18:40:18.954 28063 28063 I TestView: MyLinearLayout drawChild end
03-14 18:40:18.954 28063 28063 I TestView: MyLinearLayout dispatchDraw end
03-14 18:40:22.152 28639 28639 I TestView: MyLinearLayout constructor1
03-14 18:40:22.155 28639 28639 I TestView: MyTextView constructor1
03-14 18:40:22.258 28639 28639 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742902 ,heightMeasureSpec = -2147482232
03-14 18:40:22.260 28639 28639 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482570 ,heightMeasureSpec = -2147482232
03-14 18:40:22.260 28639 28639 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742902 ,heightMeasureSpec = -2147482232
03-14 18:40:22.277 28639 28639 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:40:22.277 28639 28639 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147482568 ,heightMeasureSpec = -2147482056
03-14 18:40:22.277 28639 28639 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:40:22.280 28639 28639 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:40:22.280 28639 28639 I TestView: MyTextView onLayout: changed = true ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 18:40:22.280 28639 28639 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:40:22.298 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:40:22.298 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:40:22.298 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:40:22.298 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:40:22.298 28639 28639 I TestView: MyTextView onDraw
03-14 18:40:22.299 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:40:22.299 28639 28639 I TestView: MyLinearLayout dispatchDraw end
03-14 18:40:34.144 28639 28639 I TestView: set INVISIBLE
03-14 18:40:45.464 28639 28639 I TestView: set VISIBLE
03-14 18:40:45.471 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:40:45.471 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:40:45.471 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:40:45.471 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:40:45.471 28639 28639 I TestView: MyTextView onDraw
03-14 18:40:45.471 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:40:45.471 28639 28639 I TestView: MyLinearLayout dispatchDraw end
03-14 18:40:52.394 28639 28639 I TestView: set GONE
03-14 18:40:56.821 28639 28639 I TestView: set VISIBLE
03-14 18:40:56.828 28639 28639 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:40:56.828 28639 28639 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742904 ,heightMeasureSpec = -2147482056
03-14 18:40:56.831 28639 28639 I TestView: MyLinearLayout onLayout start: changed = false ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:40:56.832 28639 28639 I TestView: MyLinearLayout onLayout end: changed = false ,left = 0 ,top = 0 ,right = 1080 ,bottom = 53
03-14 18:40:56.838 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:40:56.838 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:40:56.838 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:40:56.838 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:40:56.839 28639 28639 I TestView: MyTextView onDraw
03-14 18:40:56.840 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:40:56.840 28639 28639 I TestView: MyLinearLayout dispatchDraw end
03-14 18:41:05.854 28639 28639 I TestView: adjustSize
03-14 18:41:10.626 28639 28639 I TestView: requestLayout
03-14 18:41:10.632 28639 28639 I TestView: MyLinearLayout onMeasure start: widthMeasureSpec = 1073742124 ,heightMeasureSpec = -2147482056
03-14 18:41:10.633 28639 28639 I TestView: MyTextView onMeasure: widthMeasureSpec = -2147483348 ,heightMeasureSpec = -2147482056
03-14 18:41:10.633 28639 28639 I TestView: MyLinearLayout onMeasure end: widthMeasureSpec = 1073742124 ,heightMeasureSpec = -2147482056
03-14 18:41:10.637 28639 28639 I TestView: MyLinearLayout onLayout start: changed = true ,left = 0 ,top = 0 ,right = 300 ,bottom = 53
03-14 18:41:10.637 28639 28639 I TestView: MyTextView onLayout: changed = false ,left = 0 ,top = 0 ,right = 209 ,bottom = 53
03-14 18:41:10.637 28639 28639 I TestView: MyLinearLayout onLayout end: changed = true ,left = 0 ,top = 0 ,right = 300 ,bottom = 53
03-14 18:41:10.641 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:41:10.641 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:41:10.641 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:41:10.641 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:41:10.641 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:41:10.641 28639 28639 I TestView: MyLinearLayout dispatchDraw end
03-14 18:41:10.654 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:41:10.654 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:41:10.654 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:41:10.654 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:41:10.654 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:41:10.655 28639 28639 I TestView: MyLinearLayout dispatchDraw end
03-14 18:41:13.262 28639 28639 I TestView: invalidate
03-14 18:41:13.271 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:41:13.271 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:41:13.271 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:41:13.272 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:41:13.272 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:41:13.272 28639 28639 I TestView: MyLinearLayout dispatchDraw end
03-14 18:41:23.573 28639 28639 I TestView: postInvalidate
03-14 18:41:23.588 28639 28639 I TestView: MyLinearLayout onDraw start
03-14 18:41:23.588 28639 28639 I TestView: MyLinearLayout onDraw end
03-14 18:41:23.588 28639 28639 I TestView: MyLinearLayout dispatchDraw start
03-14 18:41:23.588 28639 28639 I TestView: MyLinearLayout drawChild start
03-14 18:41:23.588 28639 28639 I TestView: MyLinearLayout drawChild end
03-14 18:41:23.588 28639 28639 I TestView: MyLinearLayout dispatchDraw end
不画图,直接分析了:
- 先 setInvisible():无任何回调。
- 然后 setVisible():重新走一遍 MyLinearLayout 和 MyTextView 的 draw 流程。
- 再 setGone():无任何回调。
- 接着 setVisible():重走一遍 MyLinearLayout 和 MyTextView 的 measure,layout 和 draw 流程。
- 调整宽高:无任何回调。
- requestLayout():重走一遍 MyLinearLayout 和 MyTextView 的 measure,layout 和 draw 流程。
- invalidate() | postInvalidate():重走一遍 MyLinearLayout 和 MyTextView 的 draw 流程。