17

I have implemented clickable Recyclerview item and set android:background="?selectableItemBackground" for click effect but while inspecting code I found this lint issue.

Lint warning : Possible overdraw: Root element paints background ?selectableItemBackground with a theme that also paints a background

Any idea to solve this warning?

My xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?selectableItemBackground"
    android:clickable="true"
    android:orientation="vertical"
    android:padding="@dimen/row_padding">

    //...
</LinearLayout >
azizbekian
  • 60,783
  • 13
  • 169
  • 249
Pratik Popat
  • 2,891
  • 20
  • 31
  • @nibarius If you know that you're only going to use this layout as a recycler view item, just ignore the warning. Or suppress it. – Eugen Pechanec Oct 11 '17 at 00:22
  • @EugenPechanec the bounty is still open so you have a chance to claim it with an answer that explains the different options (suppressing the warning, removing background from the activity, setting ripple effect on the foreground). – nibarius Oct 12 '17 at 06:59

3 Answers3

14

By default, a theme has android:windowBackground attribute specified, which specifies, as the name implies, the background of the window, where your activity is being launched.

This lint warning just tells you following:

Hey! I see your theme has a windowBackground applied, and your root layout draws some other drawable on top of window background, making window's background pointless - thus overdrawing pixels needlessly.

Nulling out windowBackground would make lint not to complain:

<style name="AppTheme" parent="...">
    ...
    <item name="android:windowBackground">@null</item>
</style>
azizbekian
  • 60,783
  • 13
  • 169
  • 249
  • 3
    This would remove the window background across the whole app, right? A bit drastic when all you want is a ripple effect on the items in your one RecyclerView. Setting windowBackround to null in my app removes the background in for example my settings activity, which I don't want to change since I don't have any RecyclerView there: https://imgur.com/a/bbHhZ – nibarius Oct 08 '17 at 05:16
  • 2
    `This would remove the window background across the whole app, right?` If you set the same theme to all of your activities - yes. But you can have style, a descendant of base style, and apply that as a theme to all activities you need, leaving all the others have base theme. You question basically was "why this happens and how to fix this?" - `windowBackground` is the answer to your question. – azizbekian Oct 08 '17 at 05:33
  • It wasn't actually me who asked the question. If I would have posted the question it would probably have been more along the lines of "How can I get a ripple effect on RecyclerView items without causing this lint issue". But regardless it's great to know why it happens. – nibarius Oct 08 '17 at 06:29
  • @azizbekian so how exactly do i enable the ripple effect on my recycler view without causing the lint warning – Samuel Silas Dec 18 '21 at 23:54
1

I would just remove the lint check. It's perfectly acceptable to have x1 overdraw for most of the apps.

There's a very good post about overdraw and performance from Romain Guy there: http://www.curious-creature.com/2012/12/01/android-performance-case-study/.

Setting <item name="android:windowBackground">@null</item> in your theme is wrong because it will remove your activity launch animation (see that post for more details about the launch animation: https://cyrilmottier.com/2013/01/23/android-app-launching-made-gorgeous/). You shouldn't do that.

Setting getWindow().setBackgroundDrawable(null) in Activity.onCreate() is doable but you have to make sure each and every pixel in your app is painted at least once since you won't have a background to paint against anymore. It's potentially dangerous for a very limited gain.

mbonnin
  • 6,893
  • 3
  • 39
  • 55
  • Firstly, there is nothing stated about animation in the post you've put a link to. Secondly, `windowBackground` has nothing to do with animation of activity, it's the background of the window. Thirdly, why do you advice to leave 1x overdraw when there's an ability not to do that? Fourthly, why do you assume, that the activity OP is asking about is the launcher activity? Can't it be an ordinary activity during app flow? – azizbekian Oct 13 '17 at 13:37
  • 1
    From the Romain Guy post: `Removing the window background: the background defined in your theme is used by the system to create preview windows when launching your application. Never set it to null unless your application is transparent.`. This is what I call the launch animation (doesn't have to be from the home launcher, can be from anywhere). About 1x overdraw, spending time removing it is a bit of a waste of time in my eyes since none of your users will notice it. But feel free to do it if you want top notch performance and your app design allows it. – mbonnin Oct 13 '17 at 13:41
-1

You should put the ripple on the foreground attribute

Laurent Russier
  • 658
  • 5
  • 24
  • That depends if you want selector below text or over text. This is a design choice. So you should put the selector wherever you want. Plus `android:foreground` is only supported on `FrameLayout`. Other views support it only after Marshmallow. – Eugen Pechanec Oct 11 '17 at 00:21
  • That will not affect the warning (which is about overdraw) in any way – mbonnin Oct 13 '17 at 12:47