“可能的透支:根元素绘制背景”

问题描述 投票:0回答:6

在我的项目上运行 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" >
android android-manifest android-theme
6个回答
31
投票

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

  • 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" >
    
  • 去掉“My xml”中的后台声明

19
投票

更新

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

原答案

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

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

要在主题上应用空背景:

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

要检查过度绘制,只需激活模拟器/设备上开发选项中的显示过度绘制选项。不要相信 100% lint 警告,因为跟踪器中存在一些我不确定是否已完全修复的错误。

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


2
投票

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

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

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


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
add
当前片段上方的片段,它将具有透明背景,因此视图将相互重叠。您将看到 2 个碎片,一个在另一个之上。

要检查此行为,您可以临时在

<item name="android:windowBackground">@color/...</item>
中的
AppTheme
中添加
styles.xml
,如上所述。


0
投票

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

<style name="MyTheme" parent="Theme.MaterialComponents.Light.Bridge">
     ...
    <item name="android:windowBackground">@color/white</item>
     ...
</style>

0
投票

如果某些屏幕的背景与常见的 AppTheme 背景不同,则扩展

AppTheme
并更改新主题中的背景。

   <style name="AppThemeWithWhiteBackground" parent="AppTheme">
        <item name="android:background">@color/white</item>
    </style>

并将该样式应用到根布局。

style="@style/AppThemeWithWhiteBackground"
© www.soinside.com 2019 - 2024. All rights reserved.