深入探讨 Android 的 View 显示过程与源码分析

文章目录

    • [1. 探讨 Android 的 View 显示过程](#1. 探讨 Android 的 View 显示过程)
      • [1.1. `onFinishInflate`](#1.1. onFinishInflate)
      • [1.2. `onAttachedToWindow`](#1.2. onAttachedToWindow)
      • [1.3. `onMeasure`](#1.3. onMeasure)
      • [1.4. `onSizeChanged`](#1.4. onSizeChanged)
      • [1.5. `onLayout`](#1.5. onLayout)
      • [1.6. `onDraw`](#1.6. onDraw)
    • [2. 系统代码分析](#2. 系统代码分析)
      • [1.1. `onFinishInflate`](#1.1. onFinishInflate)
      • [1.2. `onAttachedToWindow`](#1.2. onAttachedToWindow)
      • [1.3. `onMeasure`](#1.3. onMeasure)
      • [1.4. `onSizeChanged`](#1.4. onSizeChanged)
      • [1.5. `onLayout`](#1.5. onLayout)
      • [1.6. `onDraw`](#1.6. onDraw)
    • [3. 视图显示过程总结](#3. 视图显示过程总结)
    • [4. 优化和性能考虑](#4. 优化和性能考虑)
    • [5. 结论](#5. 结论)
    • [6. 进一步深入探讨 Android 的 View 显示过程](#6. 进一步深入探讨 Android 的 View 显示过程)
      • [6.1. `onFinishInflate`](#6.1. onFinishInflate)
      • [6.2. `onAttachedToWindow`](#6.2. onAttachedToWindow)
      • [6.3. `onMeasure`](#6.3. onMeasure)
      • [6.4. `onSizeChanged`](#6.4. onSizeChanged)
      • [6.5. `onLayout`](#6.5. onLayout)
      • [6.6. `onDraw`](#6.6. onDraw)
    • [7. 视图显示过程总结(续)](#7. 视图显示过程总结(续))

1. 探讨 Android 的 View 显示过程

在 Android 中,View 的显示过程涉及多个步骤和方法,从底层到上层依次执行。理解这些步骤和方法对优化 UI 性能和实现复杂的自定义 View 非常重要。

1.1. onFinishInflate

当一个 View 从 XML 布局文件中被加载并完成所有子 View 的初始化时,onFinishInflate 方法被调用。这个方法在整个布局层次结构被完全创建之后调用,可以在这里进行一些额外的初始化工作。

java 复制代码
@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    // 视图和子视图的初始化工作
}

1.2. onAttachedToWindow

当一个 View 被附加到一个窗口时,onAttachedToWindow 方法被调用。在这个方法中,可以进行一些与窗口相关的初始化工作,例如启动动画、设置监听器等。

java 复制代码
@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    // 视图附加到窗口后的操作
}

1.3. onMeasure

onMeasure 方法用于测量 View 的大小。这个方法在布局过程中多次调用,用于确定每个 View 的宽度和高度。自定义 View 时,通常需要重写这个方法以处理特定的测量需求。

java 复制代码
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    setMeasuredDimension(width, height);
}

1.4. onSizeChanged

当 View 的大小发生变化时,onSizeChanged 方法被调用。这通常发生在 View 的初次布局和大小调整时。在这个方法中,可以根据新的大小进行调整。

java 复制代码
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    // 视图大小改变后的操作
}

1.5. onLayout

onLayout 方法用于为 View 的所有子 View 安置位置。这个方法在布局过程中调用,用于确定子 View 的位置。

java 复制代码
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    // 布局子视图的位置
    int childLeft = 0;
    int childTop = 0;
    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
        childTop += child.getMeasuredHeight();
    }
}

1.6. onDraw

onDraw 方法用于绘制 View 的内容。在这个方法中,可以使用 Canvas 对象进行绘制操作,例如绘制文本、图形等。自定义 View 时,通常需要重写这个方法以实现特定的绘制需求。

java 复制代码
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 自定义绘制操作
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}

2. 系统代码分析

1.1. onFinishInflate

ViewGroup 类中,当所有的子 View 都被加载并添加到父 View 时,onFinishInflate 方法被调用。它确保了布局的完整性和一致性。

1.2. onAttachedToWindow

onAttachedToWindow 方法在 View 的 ViewRootImpl 被创建并与窗口关联时调用。它确保 View 可以访问窗口相关的资源和服务。

1.3. onMeasure

onMeasure 方法是 View 类中的一个核心方法,它通过 MeasureSpec 参数来计算 View 的大小。MeasureSpec 包含测量模式和尺寸信息。

java 复制代码
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    // 自定义测量逻辑
}

1.4. onSizeChanged

onSizeChanged 方法在 View 类中实现,用于处理 View 大小的变化。它提供了新旧尺寸的信息,以便在大小变化时进行相应的调整。

1.5. onLayout

onLayout 方法在 ViewGroup 类中实现,用于布置子 View 的位置。它通过遍历子 View 并调用每个子 View 的 layout 方法来实现布局。

1.6. onDraw

onDraw 方法在 View 类中实现,用于绘制 View 的内容。Canvas 对象提供了一系列绘制方法,可以在 onDraw 方法中调用这些方法进行自定义绘制。

3. 视图显示过程总结

  1. 视图加载和初始化

    • XML 布局文件被解析并创建 View 实例。
    • onFinishInflate 方法被调用,完成视图和子视图的初始化。
  2. 视图附加到窗口

    • 当 View 被添加到窗口时,onAttachedToWindow 方法被调用。
    • 可以在此方法中进行与窗口相关的初始化工作。
  3. 测量视图

    • 在布局过程中,onMeasure 方法被调用,用于测量 View 的大小。
    • 通过 MeasureSpec 参数来确定 View 的测量模式和尺寸。
  4. 视图大小变化

    • 当 View 的大小发生变化时,onSizeChanged 方法被调用。
    • 可以在此方法中根据新的大小进行调整。
  5. 布局子视图

    • 在布局过程中,onLayout 方法被调用,用于布置子 View 的位置。
    • 通过遍历子 View 并调用每个子 View 的 layout 方法来实现布局。
  6. 绘制视图

    • 在绘制过程中,onDraw 方法被调用,用于绘制 View 的内容。
    • 可以在 onDraw 方法中使用 Canvas 对象进行自定义绘制。

4. 优化和性能考虑

  • 视图层次结构优化:避免过深的视图层次结构,尽量减少布局嵌套。
  • 异步任务:避免在主线程中执行耗时操作,使用异步任务处理。
  • 内存管理:及时释放不再需要的资源,避免内存泄漏。

5. 结论

通过深入理解和合理使用 Android 中的 View 显示过程,可以构建出高效、稳定且用户体验良好的应用程序。掌握这些关键技术和设计模式,不仅可以提高开发效率,还能显著提升应用的整体质量。在实际开发中,灵活应用这些技术,结合实际需求进行优化和调整,是构建优秀 Android 应用的基础。

6. 进一步深入探讨 Android 的 View 显示过程

为了更好地理解 Android View 的显示过程,我们需要深入分析系统源码中的具体实现。以下是一些关键方法在系统源码中的详细说明。

6.1. onFinishInflate

ViewGroup.java 中,onFinishInflate 方法的定义如下:

java 复制代码
protected void onFinishInflate() {
    // This is called after a view and all of its children has been inflated
}

这个方法被调用时,整个布局树已经被完全构建,可以在此处进行一些额外的初始化工作。

6.2. onAttachedToWindow

View.java 中,onAttachedToWindow 方法的定义如下:

java 复制代码
protected void onAttachedToWindow() {
    mAttachInfo = mParent.getViewRootImpl().mAttachInfo;
    if (mOverlay != null) {
        mOverlay.getOverlayView().dispatchAttachedToWindow(mAttachInfo, mWindowAttachCount);
    }
    onVisibilityAggregated(isAggregatedVisible());
    if ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
        refreshDrawableState();
    }
    // Additional operations when the view is attached to the window
}

这个方法确保了 View 能够访问与窗口相关的资源和服务。

6.3. onMeasure

onMeasure 方法在 View.java 中的实现如下:

java 复制代码
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    // Measure the view dimensions
    int width;
    int height;

    if (widthMode == MeasureSpec.EXACTLY) {
        width = widthSize;
    } else {
        // Measure the width based on the content and padding
        width = computeWidth();
    }

    if (heightMode == MeasureSpec.EXACTLY) {
        height = heightSize;
    } else {
        // Measure the height based on the content and padding
        height = computeHeight();
    }

    setMeasuredDimension(width, height);
}

onMeasure 方法通过 MeasureSpec 参数确定 View 的测量模式和尺寸。

6.4. onSizeChanged

onSizeChanged 方法在 View.java 中的实现如下:

java 复制代码
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    // Handle the size change
    if (w != oldw || h != oldh) {
        // Perform any operations needed when the size changes
    }
}

这个方法提供了新旧尺寸的信息,以便在大小变化时进行相应的调整。

6.5. onLayout

onLayout 方法在 ViewGroup.java 中的实现如下:

java 复制代码
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    int count = getChildCount();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            int childLeft = // Calculate the child's left position
            int childTop = // Calculate the child's top position
            child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
        }
    }
}

onLayout 方法遍历子 View 并调用每个子 View 的 layout 方法来实现布局。

6.6. onDraw

onDraw 方法在 View.java 中的实现如下:

java 复制代码
protected void onDraw(Canvas canvas) {
    // Perform custom drawing operations
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}

onDraw 方法使用 Canvas 对象进行自定义绘制。

7. 视图显示过程总结(续)

  1. 视图加载和初始化

    • 解析 XML 布局文件并创建 View 实例。
    • 调用 onFinishInflate 方法,完成视图和子视图的初始化。
  2. 视图附加到窗口

    • View 被添加到窗口时调用 onAttachedToWindow 方法。
    • 进行与窗口相关的初始化工作。
  3. 测量视图

    • 布局过程中调用 onMeasure 方法测量 View 的大小。
    • 使用 MeasureSpec 参数确定测量模式和尺寸。
  4. 视图大小变化

    • View 大小变化时调用 onSizeChanged 方法。
    • 根据新的大小进行调整。
  5. 布局子视图

    • 布局过程中调用 onLayout 方法布置子 View 的位置。
    • 遍历子 View 并调用每个子 View 的 layout 方法实现布局。
  6. 绘制视图

    • 绘制过程中调用 onDraw 方法绘制 View 的内容。
    • 使用 Canvas 对象进行自定义绘制。

|----------------------------------|
| 欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力 |

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
哈基米南北2 天前
ViewRootImpl 事件分发责任链分析
源码
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas