安卓View绘制流程以及事件分发流程

167 阅读3分钟

一、技术含义

在安卓中,View是所有用户界面的基石,它负责将布局文件转换为屏幕上的实际像素。View的绘制流程包括三个阶段:测量(measure)、布局(layout)和绘制(draw)。而事件分发流程则是指当一个事件被触发时,系统如何将它传递给正确的视图来处理。

二、实现原理

  1. View绘制流程 image.png

View的绘制流程可以分为三个阶段:

  • 测量(measure):确定View的宽高。
  • 布局(layout):确定View的位置。
  • 绘制(draw):将View绘制到屏幕上。

image.png

这三个阶段是通过View的三个方法来实现的:onMeasure()、onLayout()和onDraw()。其中,onMeasure()方法用于测量View的宽高;onLayout()方法用于确定View的位置;onDraw()方法用于将View绘制到屏幕上。

  1. 事件分发流程

事件分发流程指的是当一个事件被触发时,系统如何将它传递给正确的视图来处理。事件分发的三个方法为:dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()。其中,dispatchTouchEvent()方法是整个事件的入口;onInterceptTouchEvent()方法用来判断当前视图是否消费这个事件;onTouchEvent()方法是实际处理事件的视图。

三、为什么要这样设计?

View绘制流程和事件分发流程的设计是为了提高应用程序的响应速度和用户体验。通过对View的绘制进行优化,可以减少不必要的绘制操作,从而提高应用程序的性能。同时,通过对事件的分发进行优化,可以更加准确地处理用户的输入事件,从而提高应用程序的交互性和用户体验。

四、基于什么设计模式进行设计的?

View绘制流程和事件分发流程是基于责任链模式进行设计的。责任链模式是一种行为设计模式,它通过将请求沿着链传递,让多个对象都有机会处理该请求。在View绘制流程和事件分发流程中,每个视图都是责任链中的一个节点,它们分别负责处理自己的绘制和事件分发任务,并将任务传递给下一个节点。这种设计模式可以提高代码的可读性和可维护性,同时也方便了扩展和维护。

五、实现原理辅助示意图

View绘制和事件分发流程图: image.png 六、作用应用场景

  1. View绘制流程适用于自定义View的开发,通过重写View的测量、布局和绘制方法,可以实现各种复杂的界面效果。例如,实现一个圆形的进度条或者一个带有阴影效果的按钮等。
  2. 事件分发流程适用于处理用户的触摸事件,例如实现滑动、长按等交互效果。例如,在一个列表视图中,当用户滑动某个列表项时,需要将该项置顶或删除等操作。

七、用kotlin语言编写使用示例代码

以下是一个简单的自定义View示例代码,用于绘制一个红色的正方形:


class MyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {
    private val paint = Paint()
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        paint.color = Color.RED
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
    }
}


    

八、使用注意事项

  1. View的绘制顺序是从上往下,从左往右进行的,如果需要改变绘制顺序,可以通过调用invalidate()方法来实现。但是需要注意的是,invalidate()方法会重新执行整个绘制流程,因此应该尽量避免频繁调用该方法。如果需要局部刷新视图,可以使用invalidate(int l, int t, int r, int b)方法来指定需要刷新的区域。
  2. 在自定义View时,需要重写onMeasure()、onLayout()和onDraw()方法,并保证它们的逻辑正确性。同时,需要注意线程安全,避免在非UI线程中修改UI。如果在非UI线程中需要修改UI,可以使用runOnUiThread()方法来将任务切换到主线程中执行。