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?


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.


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.


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.


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.


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


12

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

das funktioniert bei mir.


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!


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

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

0

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


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


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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.