setBackground vs setBackgroundDrawable (Android)

258

Je veux définir l'arrière-plan dessinable d'une vue. Il existe deux méthodes pour cela (pour autant que je vois): setBackgroundet setBackgroundDrawable.

Lorsque j'utilise setBackground, il dit qu'il a été ajouté au niveau API 16 mais la version minimale du SDK de mon projet est 7. Je suppose que cela ne fonctionnera pas en dessous de 16, ai-je raison? Mais quand j'utilise setBackgroundDrawable, il dit que c'est obsolète.

Que dois-je utiliser?

Pijusn
la source
Utilisez: image.setImageResource (R.drawable.icon_dot1);
Brave

Réponses:

403

Il est obsolète, mais il fonctionne toujours, vous pouvez donc simplement l'utiliser. Mais si vous voulez être complètement correct, juste pour l'exhaustivité ... Vous feriez quelque chose comme ceci:

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

Pour que cela fonctionne, vous devez définir buildTarget api 16 et min build à 7 ou quelque chose de similaire.

Warpzit
la source
4
Il se plaint toujours de la dépréciation de setBackgroundDrawable. Dois-je vraiment supprimer les avertissements juste parce que Google voulait changer le nom de la méthode?
Charlie-Blake
2
@ santirivera92 Oui, vous pouvez, sinon vous pouvez créer 2 projets 1 ciblage avant qu'il ne soit un problème et 1 après. Cela vous semble-t-il une option facile? (En fait, parfois, il le fait, tant de correctifs dans ICS)
Warpzit
4
J'ai défini android:minSdkVersion="7" android:targetSdkVersion="17", mais setBackground () apparaît comme une erreur: l' appel nécessite le niveau 16 de l'API
Jonny
20
Cela m'a empêché de compiler. J'ai mis le code problématique dans sa propre fonction et désactivé les peluches uniquement pour cette fonction comme celle-ci. @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
2
@Snicolas Oui, l'IDE ou Android devrait pouvoir faire ce genre de logique pour nous.
Warpzit
111

Vous pouvez utiliser à la setBackgroundResource()place ce qui est au niveau 1 de l'API.

Ludovic
la source
78
... mais seulement si vous avez un identifiant de ressource et non une classe personnalisable que vous avez créée!
Zordid
il n'y a pas de méthode pour récupérer l'ID d'un dessin sur lequel vous avez une référence?
Poutrathor
2
setBackgroundResource () n'est pas une alternative à setBackgroundDrawable (); ou setBackground () ;. Pas du tout lié, le premier à ajouter des ressources dessinables et les autres à ajouter des dessins personnalisables.
MBH
Que se passe-t-il si je dois définir l'arrière-plan à plusieurs reprises, par exemple dans la vue de liste? setBackgroundResource(int)accepte l'ID de ressource, il doit donc gonfler la vue à chaque fois pour définir l'arrière-plan. Je ne veux pas un tel comportement, en supposant que j'ai déjà gonflé Drawable. Suis-je en train de manquer quelque chose?
azizbek
que faire si je n'ai que le drawable!?
MBH
55

semble qu'il n'y ait actuellement aucune différence entre les 2 fonctions, comme le montre le code source (crédit à ce post ):

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

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

il s'agit donc simplement d'une décision de dénomination, similaire à celle avec fill-parent vs match-parent.

développeur android
la source
5
génial! Merci. Idiot qu'un avertissement soit généré pour quelque chose d'aussi boiteux qu'une fonction renommée.
Someone Somewhere
1
@ M.kazemAkhgary Ce n'est pas la première fois qu'ils déconseillent quelque chose uniquement pour changer de nom. Ils ont changé "fill_parent" en "match_parent" pour les valeurs des paramètres de mise en page. Les deux sont exactement la même chose, pointant vers la même valeur ..
développeur Android
18

je sais que c'est une vieille question mais j'ai une situation similaire, et ma solution était

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

et puis vous pouvez jouer avec le "Drawable", appliquer des filtres de couleur, etc.

Jose De Gouveia
la source
6
Cela ne fonctionne que si l'image d'origine provient d'une ressource.
Matt Huggins
Cela ne répond même pas à la question du PO.
Petro
13

Utilisation ViewCompat.setBackground(view, background);

krawa
la source
12

vous pouvez utiliser à la setBackgroundResource()place, c.-à-d.relativeLayout.setBackgroundResource(R.drawable.back);

cela fonctionne pour moi.

ponnex
la source
7

Vous pouvez maintenant utiliser l'une de ces options. Et ça va marcher dans tous les cas. Votre couleur peut être un code HEX , comme ceci:

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

Une ressource couleur , comme celle-ci:

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

Ou une ressource xml personnalisée , comme ceci:

myView.setBackgroundResource(R.drawable.my_custom_background);

J'espère que ça aide!

Geraldo Neto
la source
6

En utilisant Android studio 1.5.1, j'ai reçu les avertissements suivants:

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

et les plaintes de dépréciation

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

En utilisant ce format, je me suis débarrassé des deux:

    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
la source
1

Cela fonctionne pour moi: la vue Vue est votre editText, spinner ... etc. Et int drawable est votre exemple d'itinéraire dessinable (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
la source
0

Utilisez setBackgroundResource (R.drawable.xml / png)

baburaoS
la source
-2

J'ai également eu ce problème, mais j'ai fait une solution de contournement en utilisant une ImageView .

Essayez d'utiliser un RelativeLayout et ajoutez une ImageView à l'intérieur (largeur et hauteur: fill_parent, scaleType: center).

Assurez-vous également que l'imageview est le premier élément à l'intérieur de RelativeLayout, afin qu'il agisse comme arrière-plan.

Jens-Joris Decorte
la source
1
En fait, cela n'aurait dû être qu'une ifclause. Voir la bonne réponse.
Pijusn
-4

Vous pouvez également le faire:

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

EDIT: Comme l'a souligné @BlazejCzapp, il est préférable d'éviter d'utiliser la réflexion si vous parvenez à résoudre le problème sans elle. J'ai eu un cas d'utilisation où je n'ai pas pu résoudre sans réflexion mais ce n'est pas le cas ci-dessus. Pour plus d'informations, veuillez consulter http://docs.oracle.com/javase/tutorial/reflect/index.html

Fabricio
la source
4
@BlazejCzapp LOL, mais cela répond à la question, donc il ne devrait pas être rétrogradé sans explication. Lorsque vous dites à un enfant de ne pas faire quelque chose sans dire pourquoi il le fera;)
Fabricio
11
Je ne veux pas m'éloigner du sujet, mais voici quelques raisons: 1. Java est un langage de type statique - utilisez le compilateur; 2. Ceci est juste une instruction if déguisée (elle obscurcit la vraie logique); 3. Il sort un canon pour tuer un moustique - ce code utilise une artillerie sérieuse pour résoudre un problème trivial; J'espère que cela le justifie quelque peu
Błażej Czapp
Merci @BlazejCzapp, vous avez raison, j'ai eu un cas d'utilisation ici où il était nécessaire de faire des choses comme le code ci-dessus, mais il ne devrait pas être utilisé s'il existe un moyen approprié de gérer cela.
Fabricio
2
C'est stupide ... il n'y a absolument aucune raison d'utiliser la réflexion pour y parvenir.
Alex Lockwood,
Oui, dites à quelqu'un qui a posé une question simple "Que dois-je utiliser?" commencer à modifier le temps d'exécution.
Petro