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.