Android应用篇 - UI 层级、过度绘制分析

过度绘制就是在同一个区域中叠加了多个控件,也就是说一个像素点上会出现多个像素的叠加,实际上呈现在我们眼前的只是最上面的一个,往往造成这种现象的原因是产品或者视觉过多繁琐的建议和交互,或者是开发人员自己不注意造成的。

目录:

  1. 如何分析过度绘制
  2. 如何解决过度绘制

1. 如何分析过度绘制

通过打开开发者选项中的"显示 GPU 过度绘制" (设置/更多设置/开发者选项/调试 GPU 过渡绘制 / 显示过渡绘制区域)来进行测试。

每个手机可能不一样,但是一定是有"调试 GPU 过渡绘制"选项 ,目前只有 Android 4.2 及以上的版本才具备此功能。

  • 1.1 颜色标识

从好到差分别是:蓝 - 绿 - 淡红 - 红。

  • 蓝色 1x 过度绘制。
  • 绿色 2x 过度绘制。
  • 淡红色 3x 过度绘制。
  • 红色超过 4x 过度绘制。
  • 1.2 验收标准

验收标准如下:

  • 控制过度绘制为 2x。
  • 不允许存在 4x 过度绘制。
  • 不允许存在面积超过屏幕 1/4 区域的 3x 过度绘制 (淡红色区域)。
  • 1.3 例子

这个页面就是超过了屏幕 1/4 的 3x 过度绘制。

2. 如何解决过度绘制

  • 2.1 减少多余的 background

这个最重要,基本上都是因为这个原因造成的,解决好背景基本上就等于解决了大多数。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:skin="http://schemas.android.com/android/skin"
  android:background="@color/common_content_bg_color"
  android:layout_height="match_parent"
  android:layout_width="match_parent"
  skin:enable="true">

  <ai.ctxc.ui.widget.TopBar
    android:id="@+id/top_bar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@color/common_content_bg_color" />

</RelativeLayout>

明显有同样的背景色重叠区域。

  • 2.2 使用 style 或者 include 复用布局

这个主要是减少重复 xml 代码用的,方便维护。同时 include 可以配合 <merge> 标签使用,减少层级。

  • 2.3 使用 ViewStub

ViewStub 需要时再加载布局。

  • 2.4 使用 sdk 提供的工具 Hierarchy Viewer 进行层级分析

主要目的是减少层级。

  • 2.5 this.getWindow().setBackgroundDrawable(null)

设置背景,这个要谨慎使用,在低端机上的使用可能会造成闪屏的情况。视图有背景,每个窗口也是有背景的。每个 Activity 是一个窗口,每个 Activity 都有不同得背景。界面的绘画顺序如下:窗口 - 跟视图 - 子视图。当我们的跟视图已经覆盖了整个窗口的时候 ,程序还是会画一个透明的窗口的背景,而这个背景用户是看不到的。我们就需要想办法让程序在这样的情况下去掉窗口背景,节约画窗口背景的时间提高效率。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 删除窗口背景
    getWindow().setBackgroundDrawable(null);
}

或者这样:

<resources>
    <style name="NoBackgroundTheme" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>
  • 2.6 clipRect()

可以通过 canvas.clipRect() 来帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。这个 API 可以很好的帮助那些有多组重叠组件的自定义 View 来控制显示的区域。同时 clipRect 方法还可以帮助节约 CPU 与 GPU 资源,在 clipRect 区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制。


使用主要是传入两个 Rect 的坐标,然后设置不同的参数来实现最终绘制的区域,教程如下:Android画布剪裁函数clipRect详解

发布了126 篇原创文章 · 获赞 215 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/u014294681/article/details/88736927