setBackground vs setBackgroundDrawable (Android)
Asked Answered
O

12

259

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?

Oxonian answered 14/8, 2012 at 7:24 Comment(1)
Use: image.setImageResource(R.drawable.icon_dot1);Allaallah
P
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.

Pyrites answered 14/8, 2012 at 7:35 Comment(15)
It still complains about setBackgroundDrawable being deprecated. Do I really have to suppresswarnings just because Google wanted to change the method name?Gariepy
@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)Pyrites
I set android:minSdkVersion="7" android:targetSdkVersion="17", however setBackground() comes out as error: Call requires API level 16 (current min is 7)Teevens
@Teevens that is a lint error/warning which you can disable. Alternatively you have to create 2 projects.Pyrites
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); } }Teevens
The answer is the right one, but really support has to do something for this. Our code is becoming awful.Triceratops
@Triceratops Yes, the IDE or Android should be able to do this kind of logic for us.Pyrites
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.Rampage
setBackgroundDrawable(); is deprecatedConcomitant
@Pyrites If I use target API as 22 is does not let me use it anyway. It shows horizontal line on the setBackgrounddrawable().Concomitant
@Pyrites 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.Straightout
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.onCreateStraightout
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.Straightout
You can suppress that one line using //noinspection deprecation above the lineLasala
@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.Pyrites
B
111

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

Balanced answered 6/2, 2013 at 9:37 Comment(5)
...but only if you got a ressource id and not a custom drawable class you created!Parous
there is no method to retrieve the ID of a drawable you have a reference on ?Cavazos
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.Telencephalon
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?Womenfolk
what if i do only have the drawable !?Telencephalon
T
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 .

Twist answered 17/9, 2013 at 7:54 Comment(2)
great! thanks. Silly that a warning is generated for something as lame as a function rename.Sturdivant
@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..Twist
S
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

Snowmobile answered 29/3, 2013 at 23:20 Comment(2)
This only works if the original image is coming from a resource.Godhead
This doesn't even answer the OP's question.Coopersmith
A
13

Use ViewCompat.setBackground(view, background);

Assibilate answered 12/12, 2016 at 10:36 Comment(0)
P
12

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

this works for me.

Pernicious answered 24/4, 2015 at 11:10 Comment(0)
S
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);
    }
Subjunction answered 22/1, 2016 at 9:10 Comment(0)
A
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!

Aceto answered 11/4, 2016 at 16:3 Comment(0)
H
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));
        }    
    }
Hairdresser answered 29/9, 2017 at 20:6 Comment(0)
S
0

Use setBackgroundResource(R.drawable.xml/png)

Stomatitis answered 1/3, 2017 at 19:56 Comment(0)
T
-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.

Tatar answered 2/8, 2014 at 11:49 Comment(1)
Actually it should have been no more than an if clause. See the correct answer.Oxonian
K
-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

Kipkipling answered 2/4, 2013 at 11:56 Comment(5)
@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 ;)Kipkipling
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 somewhatIndigested
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.Kipkipling
This is dumb... there is absolutely no reason to use reflection to achieve this.Febrile
Yes tell someone who asked a simple question "What am I supposed to use?" start modifying the run-time.Coopersmith

© 2022 - 2024 — McMap. All rights reserved.