38

在我的项目上运行 Android Lint 时,我遇到了这个警告

可能的过度绘制:根元素使用同时绘制背景的主题绘制背景 @drawable/main

推断的主题在哪里@android:style/Theme.NoTitleBar.Fullscreen

有人可以向我解释为什么会这样以及如何删除它吗?

我的xml:

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/main" //***LINT warning***
        android:orientation="vertical"
        android:weightSum="3" >

定义主题的清单部分

 <application
        android:icon="@drawable/ic_logo"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
4

5 回答 5

30

要优化您的应用程序性能(避免过度绘制),您可以执行以下操作:

  • 声明一个主题res/values/styles.xml

    <style name="MyTheme" parent="android:Theme">
        <item name="android:background">@drawable/main</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>
    

  • 更改清单:

    <application
        android:icon="@drawable/ic_logo"
        android:label="@string/app_name"
        android:theme="@style/MyTheme" >
    
  • 删除“我的 xml”中的背景声明
于 2012-08-24T16:05:02.277 回答
18

更新

查看评论或查看此链接。正如 Marcin 所提到的,我在这里的解决方案不是一个好方法,因为它会导致伪影。我一直在使用它来避免透支很长一段时间没有任何问题,但根据 Chet Haase 对此技术的评论,总的来说可能不是规则的拇指。

原始答案

我发现的最佳方法是将默认背景设置为 null 并在每个布局中应用您需要的背景。

原因是当您在主题中设置默认背景时,甚至如上所述设置具有不同背景的不同主题时,这意味着整个布局将被该背景填充。在大多数情况下,您不需要背景填充 100% 的屏幕,因为您在该背景之上有工具栏、页眉、页脚和其他元素,这些元素会导致过度绘制。

在主题上应用空背景:

<style
    name="ThemeName" parent="ParentTheme">
    <item name="android:windowBackground">@null</item>
</style>

要检查透支,只需在您的模拟器/设备的开发选项中激活 Show Overdraw 选项。不要相信 100% 的 lint 警告,因为跟踪器中存在一些我不确定是否完全修复的错误。

更多信息: 什么是透支以及为什么会出现问题?

于 2015-06-11T12:52:08.403 回答
2

您收到此 lint 警告的原因是您的活动和线性布局都尝试绘制背景。因此可见区域被绘制了两次。

如何调试这个?运行 sdk/tools/hierarchyviewer 并检查视图层次结构以查看哪个视图具有未显示的背景。(您需要有一个运行 dev build rom 的 android 设备)

什么在引擎盖下运行?请注意,几乎所有 android 主题都指定了背景,这意味着如果您想创建一个覆盖整个屏幕并带有背景的“LinearLayout”,您最好设置活动的 windowBackground="@null" 或删除背景设置线性布局。

于 2014-12-17T20:24:07.243 回答
0

如果您有replace彼此的片段FragmentManager,您可以删除背景的其他图纸。

所以,如果你有

val fragment = YourFragment.newInstance()
parentFragmentManager.beginTransaction().run {
    replace(R.id.container, fragment, YourFragment.TAG)
    addToBackStack(YourFragment.TAG)
}.commitAllowingStateLoss()

然后片段将替换当前片段并具有活动的背景。在这种情况下,您可以省略android:background="@color/..."片段。

但是,如果您使用 删除android:background添加当前片段上方的片段add,它将具有透明背景,因此视图将相互重叠。您将看到 2 个片段,一个在另一个之上。

要检查此行为,您可以临时添加<item name="android:windowBackground">@color/...</item>in AppThemestyles.xml如上所述。

于 2020-10-02T10:40:20.097 回答
0

更暴力的方法。在您的自定义 theme.xml

<style name="MyTheme" parent="Theme.MaterialComponents.Light.Bridge">
     ...
    <item name="android:windowBackground">@color/white</item>
     ...
</style>
于 2021-02-15T09:58:39.707 回答