setBackground vs setBackgroundDrawable (Android)

258

Ich möchte den Hintergrund einer Ansicht zeichnen lassen. Dafür gibt es zwei Methoden (soweit ich sehe): setBackgroundund setBackgroundDrawable.

Wenn ich es verwende setBackground, heißt es, dass es in API-Level 16 hinzugefügt wurde, aber die minimale SDK-Version meines Projekts ist 7. Ich gehe davon aus, dass es bei nichts unter 16 funktionieren wird, habe ich Recht? Aber wenn ich setBackgroundDrawable verwende, heißt es, dass es veraltet ist.

Was soll ich verwenden?

Pijusn
quelle
Verwenden Sie: image.setImageResource (R.drawable.icon_dot1);
Mutig

Antworten:

403

Es ist veraltet, aber es funktioniert immer noch, so dass Sie es einfach verwenden können. Aber wenn Sie völlig korrekt sein wollen, nur der Vollständigkeit halber ... Sie würden so etwas wie das Folgende tun:

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

Damit dies funktioniert, müssen Sie buildTarget api 16 und min build auf 7 oder ähnliches setzen.

Warpzit
quelle
4
Es beschwert sich immer noch darüber, dass setBackgroundDrawable veraltet ist. Muss ich Warnungen wirklich unterdrücken, nur weil Google den Methodennamen ändern wollte?
Charlie-Blake
2
@ santirivera92 Ja, alternativ können Sie 2 Projekte erstellen, 1 Targeting, bevor es ein Problem war, und 1 danach. Klingt das nach einer einfachen Option? (Eigentlich manchmal, so viele Korrekturen in ICS)
Warpzit
4
Ich setze android:minSdkVersion="7" android:targetSdkVersion="17"jedoch setBackground () als Fehler: Aufruf erfordert API Level 16 (aktuelle min ist 7)
Jonny
20
Es hat mich am Kompilieren gehindert. Ich habe den problematischen Code in eine eigene Funktion versetzt und Flusen nur für diese Funktion wie diese deaktiviert. @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 Ja, die IDE oder Android sollten diese Art von Logik für uns ausführen können.
Warpzit
111

Sie können setBackgroundResource()stattdessen die API-Ebene 1 verwenden.

Ludovic
quelle
78
... aber nur, wenn Sie eine Ressourcen-ID und keine benutzerdefinierte Zeichenklasse haben, die Sie erstellt haben!
Zordid
Gibt es keine Methode, um die ID eines Zeichens abzurufen, auf das Sie eine Referenz haben?
Poutrathor
2
setBackgroundResource () ist keine Alternative zu setBackgroundDrawable (); oder setBackground ();. Überhaupt nicht verwandt, der erste, der eine Ressource zum Zeichnen hinzufügt, und der andere, der die Option CUSTOM drawable hinzufügt.
MBH
Was ist, wenn ich den Hintergrund wiederholt einstellen muss, beispielsweise in der Listenansicht? setBackgroundResource(int)Akzeptiert die Ressourcen-ID, daher muss die Ansicht jedes Mal aufgeblasen werden, um den Hintergrund festzulegen. Ich möchte ein solches Verhalten nicht, vorausgesetzt, ich habe Drawable bereits aufgeblasen. Vermisse ich etwas
Azizbekian
Was ist, wenn ich nur das Drawable habe?
MBH
55

Anscheinend gibt es derzeit keinen Unterschied zwischen den beiden Funktionen, wie im Quellcode angegeben (Gutschrift für diesen Beitrag ):

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

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

Es handelt sich also nur um eine Namensentscheidung, ähnlich der mit Fill-Parent gegen Match-Parent.

Android-Entwickler
quelle
5
großartig! Vielen Dank. Es ist albern, dass eine Warnung für etwas generiert wird, das so lahm ist wie das Umbenennen einer Funktion.
Jemand irgendwo
1
@ M.kazemAkhgary Es ist nicht das erste Mal, dass sie etwas nur zur Namensänderung ablehnen. Sie hatten "fill_parent" für Layoutparameterwerte in "match_parent" geändert. Beide sind genau das gleiche und zeigen auf den gleichen Wert ..
Android-Entwickler
18

Ich weiß, dass dies eine alte Frage ist, aber ich habe eine ähnliche Situation, und meine Lösung war

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

und dann können Sie mit dem "Drawable" spielen, Farbfilter anwenden usw.

Jose De Gouveia
quelle
6
Dies funktioniert nur, wenn das Originalbild von einer Ressource stammt.
Matt Huggins
Dies beantwortet nicht einmal die Frage des OP.
Petro
13

Verwenden ViewCompat.setBackground(view, background);

Krawa
quelle
12

Sie könnten setBackgroundResource()stattdessen verwenden, dhrelativeLayout.setBackgroundResource(R.drawable.back);

das funktioniert bei mir.

ponnex
quelle
7

Jetzt können Sie eine dieser Optionen verwenden. Und es wird auf jeden Fall funktionieren. Ihre Farbe kann ein HEX-Code sein , wie folgt:

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

Eine Farbressource wie diese:

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

Oder eine benutzerdefinierte XML-Ressource wie folgt:

myView.setBackgroundResource(R.drawable.my_custom_background);

Ich hoffe es hilft!

Geraldo Neto
quelle
6

Mit Android Studio 1.5.1 habe ich folgende Warnungen erhalten:

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

und die Beschwerden über die Abschreibung

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

Mit diesem Format habe ich beide losgeworden:

    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
quelle
1

Das funktioniert bei mir: Ansicht Ansicht ist Ihr editText, Spinner ... etc. Und int drawable ist Ihr Beispiel für eine zeichnbare Route (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
quelle
0

Verwenden Sie setBackgroundResource (R.drawable.xml / png)

baburaoS
quelle
-2

Ich hatte auch dieses Problem, aber ich habe eine Problemumgehung mit einer ImageView durchgeführt .

Versuchen Sie es mit einem RelativeLayout und fügen Sie eine ImageView hinzu (Breite und Höhe: fill_parent, scaleType: center).

Stellen Sie außerdem sicher, dass die Bildansicht das erste Element im RelativeLayout ist, damit sie als Hintergrund fungiert.

Jens-Joris Decorte
quelle
1
Eigentlich sollte es nicht mehr als eine ifKlausel sein. Siehe die richtige Antwort.
Pijusn
-4

Sie können dies auch tun:

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

BEARBEITEN: Wie von @BlazejCzapp hervorgehoben , ist es vorzuziehen, die Verwendung von Reflexion zu vermeiden, wenn Sie das Problem ohne sie lösen können. Ich hatte einen Anwendungsfall, in dem ich nicht ohne Reflexion lösen konnte, aber das ist oben nicht der Fall. Weitere Informationen finden Sie unter http://docs.oracle.com/javase/tutorial/reflect/index.html

Fabricio
quelle
4
@BlazejCzapp LOL, aber es beantwortet die Frage, daher sollte es nicht ohne eine Erklärung herabgestimmt werden. Wenn Sie einem Kind sagen, dass es etwas nicht tun soll, ohne zu sagen, warum es das tun wird;)
Fabricio
11
Ich möchte nicht vom Thema abweichen, aber hier sind einige Gründe: 1. Java ist eine statisch typisierte Sprache - verwenden Sie den Compiler; 2. Dies ist nur eine getarnte if-Aussage (sie verschleiert die wahre Logik); 3. Es bringt eine Kanone heraus, um eine Mücke zu töten - dieser Code verwendet ernsthafte Artillerie, um ein triviales Problem zu lösen. Hoffe, das rechtfertigt es etwas
Błażej Czapp
Danke @BlazejCzapp, Sie haben Recht, ich hatte hier einen Anwendungsfall, in dem es notwendig war, Dinge wie den obigen Code zu tun, aber er sollte nicht verwendet werden, wenn es einen richtigen Weg gibt, damit umzugehen.
Fabricio
2
Das ist dumm ... es gibt absolut keinen Grund, Reflexion zu verwenden, um dies zu erreichen.
Alex Lockwood
Ja, sagen Sie jemandem, der eine einfache Frage gestellt hat: "Was soll ich verwenden?" Ändern Sie die Laufzeit.
Petro