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

打印 上一主题 下一主题

主题 1004|帖子 1004|积分 3012

1. 探究 Android 的 View 显示过程

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

当一个 View 从 XML 布局文件中被加载并完成所有子 View 的初始化时,onFinishInflate 方法被调用。这个方法在整个布局层次结构被完全创建之后调用,可以在这里举行一些额外的初始化工作。
  1. @Override
  2. protected void onFinishInflate() {
  3.     super.onFinishInflate();
  4.     // 视图和子视图的初始化工作
  5. }
复制代码
1.2. onAttachedToWindow

当一个 View 被附加到一个窗口时,onAttachedToWindow 方法被调用。在这个方法中,可以举行一些与窗口相关的初始化工作,例如启动动画、设置监听器等。
  1. @Override
  2. protected void onAttachedToWindow() {
  3.     super.onAttachedToWindow();
  4.     // 视图附加到窗口后的操作
  5. }
复制代码
1.3. onMeasure

onMeasure 方法用于测量 View 的巨细。这个方法在布局过程中多次调用,用于确定每个 View 的宽度和高度。自定义 View 时,通常必要重写这个方法以处理特定的测量需求。
  1. @Override
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  3.     super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  4.     int width = MeasureSpec.getSize(widthMeasureSpec);
  5.     int height = MeasureSpec.getSize(heightMeasureSpec);
  6.     setMeasuredDimension(width, height);
  7. }
复制代码
1.4. onSizeChanged

当 View 的巨细发生变化时,onSizeChanged 方法被调用。这通常发生在 View 的初次布局和巨细调整时。在这个方法中,可以根据新的巨细举行调整。
  1. @Override
  2. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  3.     super.onSizeChanged(w, h, oldw, oldh);
  4.     // 视图大小改变后的操作
  5. }
复制代码
1.5. onLayout

onLayout 方法用于为 View 的所有子 View 安置位置。这个方法在布局过程中调用,用于确定子 View 的位置。
  1. @Override
  2. protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
  3.     super.onLayout(changed, left, top, right, bottom);
  4.     // 布局子视图的位置
  5.     int childLeft = 0;
  6.     int childTop = 0;
  7.     for (int i = 0; i < getChildCount(); i++) {
  8.         View child = getChildAt(i);
  9.         child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
  10.         childTop += child.getMeasuredHeight();
  11.     }
  12. }
复制代码
1.6. onDraw

onDraw 方法用于绘制 View 的内容。在这个方法中,可以使用 Canvas 对象举行绘制操作,例如绘制文本、图形等。自定义 View 时,通常必要重写这个方法以实现特定的绘制需求。
  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3.     super.onDraw(canvas);
  4.     // 自定义绘制操作
  5.     Paint paint = new Paint();
  6.     paint.setColor(Color.RED);
  7.     canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
  8. }
复制代码
2. 体系代码分析

1.1. onFinishInflate

在 ViewGroup 类中,当所有的子 View 都被加载并添加到父 View 时,onFinishInflate 方法被调用。它确保了布局的完备性和同等性。
1.2. onAttachedToWindow

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

onMeasure 方法是 View 类中的一个焦点方法,它通过 MeasureSpec 参数来盘算 View 的巨细。MeasureSpec 包含测量模式和尺寸信息。
  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  2.     int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  3.     int widthSize = MeasureSpec.getSize(widthMeasureSpec);
  4.     int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  5.     int heightSize = MeasureSpec.getSize(heightMeasureSpec);
  6.     // 自定义测量逻辑
  7. }
复制代码
1.4. onSizeChanged

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

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

onDraw 方法在 View 类中实现,用于绘制 View 的内容。Canvas 对象提供了一系列绘制方法,可以在 onDraw 方法中调用这些方法举行自定义绘制。
3. 视图显示过程总结


  • 视图加载和初始化

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

  • 视图附加到窗口

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

  • 测量视图

    • 在布局过程中,onMeasure 方法被调用,用于测量 View 的巨细。
    • 通过 MeasureSpec 参数来确定 View 的测量模式和尺寸。

  • 视图巨细变化

    • 当 View 的巨细发生变化时,onSizeChanged 方法被调用。
    • 可以在此方法中根据新的巨细举行调整。

  • 布局子视图

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

  • 绘制视图

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

4. 优化和性能考虑



  • 视图层次结构优化:避免过深的视图层次结构,尽量减少布局嵌套。
  • 异步使命:避免在主线程中实行耗时操作,使用异步使命处理。
  • 内存管理:及时开释不再必要的资源,避免内存走漏。
5. 结论

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

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

在 ViewGroup.java 中,onFinishInflate 方法的定义如下:
  1. protected void onFinishInflate() {
  2.     // This is called after a view and all of its children has been inflated
  3. }
复制代码
这个方法被调用时,整个布局树已经被完全构建,可以在此处举行一些额外的初始化工作。
6.2. onAttachedToWindow

在 View.java 中,onAttachedToWindow 方法的定义如下:
  1. protected void onAttachedToWindow() {
  2.     mAttachInfo = mParent.getViewRootImpl().mAttachInfo;
  3.     if (mOverlay != null) {
  4.         mOverlay.getOverlayView().dispatchAttachedToWindow(mAttachInfo, mWindowAttachCount);
  5.     }
  6.     onVisibilityAggregated(isAggregatedVisible());
  7.     if ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
  8.         refreshDrawableState();
  9.     }
  10.     // Additional operations when the view is attached to the window
  11. }
复制代码
这个方法确保了 View 能够访问与窗口相关的资源和服务。
6.3. onMeasure

onMeasure 方法在 View.java 中的实现如下:
  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  2.     int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  3.     int widthSize = MeasureSpec.getSize(widthMeasureSpec);
  4.     int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  5.     int heightSize = MeasureSpec.getSize(heightMeasureSpec);
  6.     // Measure the view dimensions
  7.     int width;
  8.     int height;
  9.     if (widthMode == MeasureSpec.EXACTLY) {
  10.         width = widthSize;
  11.     } else {
  12.         // Measure the width based on the content and padding
  13.         width = computeWidth();
  14.     }
  15.     if (heightMode == MeasureSpec.EXACTLY) {
  16.         height = heightSize;
  17.     } else {
  18.         // Measure the height based on the content and padding
  19.         height = computeHeight();
  20.     }
  21.     setMeasuredDimension(width, height);
  22. }
复制代码
onMeasure 方法通过 MeasureSpec 参数确定 View 的测量模式和尺寸。
6.4. onSizeChanged

onSizeChanged 方法在 View.java 中的实现如下:
  1. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  2.     // Handle the size change
  3.     if (w != oldw || h != oldh) {
  4.         // Perform any operations needed when the size changes
  5.     }
  6. }
复制代码
这个方法提供了新旧尺寸的信息,以便在巨细变化时举行相应的调整。
6.5. onLayout

onLayout 方法在 ViewGroup.java 中的实现如下:
  1. protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
  2.     int count = getChildCount();
  3.     for (int i = 0; i < count; i++) {
  4.         View child = getChildAt(i);
  5.         if (child.getVisibility() != GONE) {
  6.             int childLeft = // Calculate the child's left position
  7.             int childTop = // Calculate the child's top position
  8.             child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
  9.         }
  10.     }
  11. }
复制代码
onLayout 方法遍历子 View 并调用每个子 View 的 layout 方法来实现布局。
6.6. onDraw

onDraw 方法在 View.java 中的实现如下:
  1. protected void onDraw(Canvas canvas) {
  2.     // Perform custom drawing operations
  3.     Paint paint = new Paint();
  4.     paint.setColor(Color.RED);
  5.     canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
  6. }
复制代码
onDraw 方法使用 Canvas 对象举行自定义绘制。
7. 视图显示过程总结(续)


  • 视图加载和初始化

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

  • 视图附加到窗口

    • View 被添加到窗口时调用 onAttachedToWindow 方法。
    • 举行与窗口相关的初始化工作。

  • 测量视图

    • 布局过程中调用 onMeasure 方法测量 View 的巨细。
    • 使用 MeasureSpec 参数确定测量模式和尺寸。

  • 视图巨细变化

    • View 巨细变化时调用 onSizeChanged 方法。
    • 根据新的巨细举行调整。

  • 布局子视图

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

  • 绘制视图

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

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表