在我的项目上运行 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" >
要优化应用程序性能(避免过度绘制),您可以执行以下操作:
在
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" >
更新
查看评论或查看此链接。正如 Marcin 提到的,我在这里的解决方案不是一个好方法,因为它可能会导致伪影。我已经使用它来避免透支很长时间了,没有任何问题,但根据 Chet Haase 对这项技术的评论,一般来说可能不是一个经验法则。
原答案
我发现的最好方法是将默认背景设置为 null 并在每个布局中应用您需要的背景。
原因是当您在主题中设置默认背景,甚至按照上面的建议设置具有不同背景的不同主题时,这意味着整个布局将填充该背景。在大多数情况下,您不需要背景填充 100% 的屏幕,因为背景上有工具栏、页眉、页脚和其他元素,这会导致过度绘制。
要在主题上应用空背景:
<style
name="ThemeName" parent="ParentTheme">
<item name="android:windowBackground">@null</item>
</style>
要检查过度绘制,只需激活模拟器/设备上开发选项中的显示过度绘制选项。不要相信 100% lint 警告,因为跟踪器中存在一些我不确定是否已完全修复的错误。
更多信息: 什么是透支以及为什么会出现问题?
您收到此 lint 警告的原因是您的活动和线性布局都尝试绘制背景。因此可见区域被绘制了两次。
如何调试? 运行 sdk/tools/hierarchyviewer 并检查视图层次结构以查看哪个视图具有未显示的背景。 (您需要有一个运行 dev build rom 的 Android 设备)
幕后运行的是什么?请注意,几乎所有 Android 主题都指定了背景,这意味着如果您想创建一个覆盖整个屏幕并带有背景的“LinearLayout”,您最好设置 Activity 的 windowBackground=" @null”或删除线性布局中的背景设置。
如果您在
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
,如上所述。
更暴力的方法。在您的自定义 theme.xml 中
<style name="MyTheme" parent="Theme.MaterialComponents.Light.Bridge">
...
<item name="android:windowBackground">@color/white</item>
...
</style>
如果某些屏幕的背景与常见的 AppTheme 背景不同,则扩展
AppTheme
并更改新主题中的背景。
<style name="AppThemeWithWhiteBackground" parent="AppTheme">
<item name="android:background">@color/white</item>
</style>
并将该样式应用到根布局。
style="@style/AppThemeWithWhiteBackground"