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

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

码农世界 2024-06-18 后端 103 次浏览 0个评论

文章目录

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

            1. 探讨 Android 的 View 显示过程

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

            1.1. onFinishInflate

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

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

            1.2. onAttachedToWindow

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

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

            1.3. onMeasure

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

            @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 的初次布局和大小调整时。在这个方法中,可以根据新的大小进行调整。

            @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 的位置。

            @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 时,通常需要重写这个方法以实现特定的绘制需求。

            @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 包含测量模式和尺寸信息。

            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 方法被调用,完成视图和子视图的初始化。
              • 视图附加到窗口:

                • 当 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 方法的定义如下:

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

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

              6.2. onAttachedToWindow

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

              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 中的实现如下:

              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 中的实现如下:

              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 中的实现如下:

              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 中的实现如下:

              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 方法,完成视图和子视图的初始化。
                • 视图附加到窗口:

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

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

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

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

                          • 绘制过程中调用 onDraw 方法绘制 View 的内容。
                          • 使用 Canvas 对象进行自定义绘制。
              欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力

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

转载请注明来自码农世界,本文标题:《深入探讨 Android 的 View 显示过程与源码分析》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,103人围观)参与讨论

还没有评论,来说两句吧...

Top