260

I want to set background drawable of a view. There are two methods for this (as far as I see): setBackground and setBackgroundDrawable.

When I use setBackground, it says it has been added in API level 16 but my project's min SDK version is 7. I assume it's not going to work on anything below 16, am I right? But when I use setBackgroundDrawable, it says it's deprecated.

What am I supposed to use?

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Pijusn
  • 11,025
  • 7
  • 57
  • 76

12 Answers12

405

It's deprecated but it still works so you could just use it. But if you want to be completly correct, just for the completeness of it... You'd do something like following:

int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
    setBackgroundDrawable();
} else {
    setBackground();
}

For this to work you need to set buildTarget api 16 and min build to 7 or something similar.

Warpzit
  • 27,966
  • 19
  • 103
  • 155
  • 4
    It still complains about setBackgroundDrawable being deprecated. Do I really have to suppresswarnings just because Google wanted to change the method name? – Charlie-Blake Oct 25 '12 at 09:07
  • 2
    @santirivera92 Yes you have, alternatively you can create 2 projects 1 targeting before it was an issue and 1 after. Does that sound like an easy option? (Actually sometimes it does, so many fixes in ICS) – Warpzit Oct 25 '12 at 09:11
  • 4
    I set `android:minSdkVersion="7" android:targetSdkVersion="17"`, however setBackground() comes out as error: **Call requires API level 16 (current min is 7)** – Jonny Jan 16 '13 at 06:12
  • @Jonny that is a lint error/warning which you can disable. Alternatively you have to create 2 projects. – Warpzit Jan 16 '13 at 06:15
  • 20
    It prevented me from compiling. I put the problematic code in its own function and disabled lint only for that function like this. `@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @SuppressWarnings("deprecation") private static void setBg(RelativeLayout layout, BitmapDrawable TileMe) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { layout.setBackgroundDrawable(TileMe); } else { layout.setBackground(TileMe); } }` – Jonny Jan 16 '13 at 06:29
  • 1
    The answer is the right one, but really support has to do something for this. Our code is becoming awful. – Snicolas Feb 25 '13 at 14:28
  • 2
    @Snicolas Yes, the IDE or Android should be able to do this kind of logic for us. – Warpzit Feb 25 '13 at 18:07
  • 1
    I also put that code into a separate function so I could put the lint and version warnings on without masking similar errors on other functions. – CoatedMoose Mar 21 '13 at 06:02
  • `setBackgroundDrawable();` is deprecated – Apurva Aug 03 '15 at 11:12
  • @Warpzit If I use target API as 22 is does not let me use it anyway. It shows horizontal line on the setBackgrounddrawable(). – Apurva Aug 04 '15 at 04:37
  • @Warpzit I know this post is quite old but I really need an answer from an android expert to my doubt, so I'm writing here. I'm following the way you mentioned above using Eclipse and it works like a charm. Because I need to support from api 16 to the latest, I'm using both new and deprecated methods and classes, and due to these lines, I see some messages like below in Logcat whenever I LAUNCH my app on OLD devices. – Jenix Mar 02 '16 at 16:45
  • E/dalvikvm(3312): Could not find class 'android.media.AudioAttributes$Builder', referenced from method com.example.sqlitetest.MainActivity.onCreate I/dalvikvm(3312): Could not find method android.speech.tts.TextToSpeech.speak, referenced from method com.example.sqlitetest.MainActivity.onCreate – Jenix Mar 02 '16 at 16:45
  • As you can see, a CLASS causes an ERROR, and a METHOD causes just an INFORMATION message. Regardless of these messages, it worked just fine and never failed so far. After it's launched, while working no error messages at all, and of course, no errors on new devices either. So I'm not sure if I can ignore these messages. – Jenix Mar 02 '16 at 16:51
  • 1
    You can suppress that one line using `//noinspection deprecation` above the line – Ali Bdeir Jul 23 '16 at 16:21
  • @M.kazemAkhgary True, but to me this seems pretty outdated either way as most people wont be using api before jelly bean. We're talking less than 1% og market. – Warpzit Oct 31 '18 at 12:19
112

You can use setBackgroundResource() instead which is in API level 1.

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
Ludovic
  • 1,294
  • 1
  • 8
  • 3
  • 80
    ...but only if you got a ressource id and not a custom drawable class you created! – Zordid Jun 10 '13 at 09:20
  • there is no method to retrieve the ID of a drawable you have a reference on ? – Poutrathor Sep 23 '14 at 15:09
  • 2
    setBackgroundResource() is not alternative to setBackgroundDrawable(); or setBackground();. Not related at all, the first one to add resource drawable and the others to add CUSTOM drawable. – MBH Feb 23 '15 at 22:21
  • What if I have to set background repeatedly, say in listview? `setBackgroundResource(int)` accepts resource id, therefore it has to inflate the view each time in order to set the background. I do not want such behaviour, assuming I already have inflated Drawable. Am I missing something? – azizbekian Dec 01 '15 at 12:30
  • what if i do only have the drawable !? – MBH Dec 12 '15 at 09:17
55

seems that currently there is no difference between the 2 functions, as shown on the source code (credit to this post) :

public void setBackground(Drawable background) {
    //noinspection deprecation
    setBackgroundDrawable(background);
}

@Deprecated
public void setBackgroundDrawable(Drawable background) { ... }

so it's just a naming decision, similar to the one with fill-parent vs match-parent .

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • 5
    great! thanks. Silly that a warning is generated for something as lame as a function rename. – Someone Somewhere Jul 23 '14 at 20:55
  • 1
    @M.kazemAkhgary It's not the first time they deprecate something only for name changing. They had "fill_parent" being changed to "match_parent" for layout params values. Both are exactly the same thing, pointing to the same value.. – android developer Oct 31 '18 at 06:16
19

i know this is an old question but i have a similar situation ,and my solution was

button.setBackgroundResource( R.drawable.ic_button );
Drawable d = button.getBackground();

and then you can play with the "Drawable", applying color filters, etc

Jose De Gouveia
  • 994
  • 1
  • 14
  • 33
13

Use ViewCompat.setBackground(view, background);

krawa
  • 583
  • 6
  • 12
12

you could use setBackgroundResource() instead i.e. relativeLayout.setBackgroundResource(R.drawable.back);

this works for me.

ponnex
  • 838
  • 5
  • 18
7

Using Android studio 1.5.1 i got the following warnings:

Call requires API level 16 (current min is 9): android.view.View#setBackground

and the complaints about deprecation

'setBackgroundDrawable(android.graphics.drawable.Drawable)' is deprecated

Using this format, i got rid of both:

    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        //noinspection deprecation
        layout.setBackgroundDrawable(drawable);
    } else {
        layout.setBackground(drawable);
    }
Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74
7

Now you can use either of those options. And it is going to work in any case. Your color can be a HEX code, like this:

myView.setBackgroundResource(ContextCompat.getColor(context, Color.parseColor("#FFFFFF")));

A color resource, like this:

myView.setBackgroundResource(ContextCompat.getColor(context,R.color.blue_background));

Or a custom xml resource, like so:

myView.setBackgroundResource(R.drawable.my_custom_background);

Hope it helps!

Geraldo Neto
  • 3,670
  • 1
  • 30
  • 33
1

This works for me: View view is your editText, spinner...etc. And int drawable is your drawable route example (R.drawable.yourDrawable)

 public void verifyDrawable (View view, int drawable){

        int sdk = Build.VERSION.SDK_INT;

        if(sdk < Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackgroundDrawable(
                    ContextCompat.getDrawable(getContext(),drawable));
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackground(getResources().getDrawable(drawable));
        }    
    }
user0987
  • 11
  • 2
0

Use setBackgroundResource(R.drawable.xml/png)

baburaoS
  • 83
  • 1
  • 6
-2

I also had this problem, but I made a workaround using a ImageView.

Try using a RelativeLayout and add a ImageView inside it (width and height: fill_parent, scaleType: center).

Also make sure the imageview is the first element inside the RelativeLayout, so it will act as background.

-4

You can also do this:

try {
     myView.getClass().getMethod(android.os.Build.VERSION.SDK_INT >= 16 ? "setBackground" : "setBackgroundDrawable", Drawable.class).invoke(myView, myBackgroundDrawable);
} catch (Exception ex) {
     // do nothing
}

EDIT: Just as pointed out by @BlazejCzapp it is preferable to avoid using reflection if you can manage to solve the problem without it. I had a use case where I was unable to solve without reflection but that is not case above. For more information please take a look at http://docs.oracle.com/javase/tutorial/reflect/index.html

Tobrun
  • 18,291
  • 10
  • 66
  • 81
Fabricio
  • 130
  • 5
  • 4
    @BlazejCzapp LOL, but it DOES answer the question, so it shouldn't be downvoted without an explanation. When you tell a child to not do something without telling why they will do that ;) – Fabricio Oct 03 '13 at 13:47
  • 11
    I don't want to go off topic, but here are some reasons: 1. Java is a statically typed language - make use the compiler; 2. This is just an if-statement in disguise (it's obfuscating the true logic); 3. It's bringing out a cannon to kill a mosquito - this code is using some serious artillery to solve a trivial problem; Hope that justifies it somewhat – Błażej Czapp Oct 03 '13 at 21:05
  • Thanks @BlazejCzapp, you are right, I had an use case here where it was necessary to do things like the code above but it shouldn't be used if there is a proper way to handle this. – Fabricio Oct 07 '13 at 17:37
  • 2
    This is dumb... there is absolutely no reason to use reflection to achieve this. – Alex Lockwood Sep 12 '14 at 19:48
  • Yes tell someone who asked a simple question "What am I supposed to use?" start modifying the run-time. – Petro Jan 04 '15 at 23:55