Android应用篇 - 从不同场景来理解 View 的绘制流程

很多文章都讲解了 View 的绘制流程,今天我想换种方式,用例子来理解。

 

目录:

  1. 准备工作
  2. 单个 View 测试
  3. 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() 回调,有两种方法:

  1. 给 ViewGroup 设置一个背景。
  2. 在构造函数里面,调用 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 流程。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值