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?


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.


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.


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.


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.


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);


12

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

cela fonctionne pour moi.


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!


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);
    }

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));
        }    
    }


-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.


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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.