40

While running Android Lint on my Project I came across this warning

Possible overdraw: Root element paints background @drawable/main with a theme that also paints a background

Where inferred theme is @android:style/Theme.NoTitleBar.Fullscreen

Can someone explain to me why is this coming and how to remove it ??

My 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" >

The part of manifest where theme is defined

 <application
        android:icon="@drawable/ic_logo"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
hasanghaforian
  • 13,858
  • 11
  • 76
  • 167
Sunny Kumar Aditya
  • 2,806
  • 4
  • 26
  • 38

5 Answers5

31

To optimize your apps performance (avoid overdraw), you can do the following:

  • declare a theme in 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>
    

  • change the Manifest:

    <application
        android:icon="@drawable/ic_logo"
        android:label="@string/app_name"
        android:theme="@style/MyTheme" >
    
  • remove the background declaration in "My xml"
Xavi
  • 20,111
  • 14
  • 72
  • 63
nvrandow
  • 722
  • 10
  • 13
18

Update

Check out the comments or check out this link. As Marcin mentions, my solution here is not a good approach since it can cause artefacts. I've been using it to avoid overdraw for a long time without any problems but in general might be not a thumb of rule according to the Chet Haase comments on this technique.

Original answer

The best approach I've found is to set as null the default background and apply the background you need in each layout.

The reason is when you set a default background in a theme, or even different themes with different backgrounds as suggested above, this means the whole layout will be fill with that background. In most cases you don't need a background filling 100% of the screen because you have toolbars, headers, footers and other elements on top of that background that will cause overdraw.

To apply null background on a theme:

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

To check overdraw just activate the Show Overdraw option in the dev options on your emulator/device. Don't trust 100% lint warnings because there was some bugs in the tracker that I'm not sure are completely fixed.

More information: What is overdraw and why is an issue?

Sotti
  • 14,089
  • 2
  • 50
  • 43
  • 1
    That's a good line of reasoning you present here, but please check out the "Avoid Null Window Backgrounds" section in [Developing for Android VIII The Rules: User Interface](https://medium.com/google-developers/developing-for-android-viii-e91ced595fac) for possible drawbacks of this approach. – Marcin Koziński Sep 14 '15 at 08:55
  • @Marcin Altho with Chet's recommendation (use the default background) is harder to avoid overdraw on toolbars and other layout elements since the background is gonna be always matching the whole screen size. – Sotti Sep 14 '15 at 09:44
2

The reason why you get this lint warning is that your activity and your linear layout both try to draw the background. Therefore the visible area is drawn twice.

How to debug this? Run sdk/tools/hierarchyviewer and inspect the view hierarchy to see which view has background that is not shown. (You need to have an android device running dev build rom)

What's running under the hood? Note that almost all android themes have background specified, which means if you ever want to create a "LinearLayout" that covers the entire screen and with a backround, you had better either set activity's windowBackground="@null" or remove the background setting in the linear layout.

Ian Wong
  • 1,617
  • 14
  • 11
0

In case you have fragments that replace each other in FragmentManager, you can remove additional drawings of the background.

So, if you have

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

then the fragment will replace a current fragment and will have the background of an activity. In this case you can omit android:background="@color/..." of the fragment.

But if you remove android:background and add the fragment above a current fragment with add, it will have a trasparent background, so that views will overlap each other. You will see 2 fragments one above other.

To check this behaviour you can temporarily add <item name="android:windowBackground">@color/...</item> in AppTheme in styles.xml, as advised above.

CoolMind
  • 26,736
  • 15
  • 188
  • 224
0

A more brute force approach. In your custom theme.xml

<style name="MyTheme" parent="Theme.MaterialComponents.Light.Bridge">
     ...
    <item name="android:windowBackground">@color/white</item>
     ...
</style>
Joe Malebe
  • 614
  • 5
  • 6