setBackground vs setBackgroundDrawable (Android)


258

Chcę ustawić tło do rysowania widoku. Są na to dwie metody (o ile mi wiadomo): setBackgroundi setBackgroundDrawable.

Kiedy używam setBackground, mówi, że został dodany na poziomie API 16, ale wersja minimalna SDK mojego projektu to 7. Zakładam, że nie będzie działał na niczym poniżej 16, prawda? Ale kiedy używam setBackgroundDrawable, mówi, że jest przestarzałe.

Z czego mam korzystać?


Użyj: image.setImageResource (R.drawable.icon_dot1);
Brave

Odpowiedzi:


403

Jest przestarzały, ale nadal działa, więc możesz go po prostu użyć. Ale jeśli chcesz być całkowicie poprawny, tylko dla kompletności tego ... Zrobiłbyś coś takiego:

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

Aby to zadziałało, musisz ustawić buildTarget API 16 i min build na 7 lub coś podobnego.


4
Nadal narzeka na wycofanie setBackgroundDrawable. Czy naprawdę muszę pomijać ostrzeżenia tylko dlatego, że Google chciał zmienić nazwę metody?
Charlie-Blake,

2
@ santirivera92 Tak, alternatywnie możesz utworzyć 2 projekty 1 kierowane przed, zanim pojawił się problem i 1 po nim. Czy to brzmi jak łatwa opcja? (Właściwie czasami tak się dzieje, tyle poprawek w ICS)
Warpzit,

4
Ustawić android:minSdkVersion="7" android:targetSdkVersion="17", jednak setBackground () wychodzi za błąd: Połączenie wymaga poziom API 16 (prąd min wynosi 7)
Jonny

20
To uniemożliwiło mi kompilację. Umieszczam problematyczny kod w jego własnej funkcji i wyłączam kłaczki tylko dla tej funkcji w ten sposób. @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 Tak, IDE lub Android powinny być w stanie wykonać dla nas taką logikę.
Warpzit,

111

Możesz użyć setBackgroundResource()zamiast tego, który jest na poziomie API 1.


78
... ale tylko jeśli masz identyfikator zasobu, a nie utworzoną przez ciebie niestandardową klasę do rysowania!
Zordid,

nie ma metody odzyskania identyfikatora wyciągu, na którym masz odniesienie?
Poutrathor,

2
setBackgroundResource () nie jest alternatywą dla setBackgroundDrawable (); lub setBackground () ;. W ogóle niezwiązany, pierwszy, który dodaje zasoby do pobrania, a drugi - NIESTANDARDOWY.
MBH

Co jeśli muszę wielokrotnie ustawiać tło, powiedzmy w widoku listy? setBackgroundResource(int)akceptuje identyfikator zasobu, dlatego za każdym razem musi nadmuchać widok, aby ustawić tło. Nie chcę takiego zachowania, zakładając, że już nadmuchałem Drawable. Czy coś brakuje?
azizbekian

co, jeśli mam tylko możliwość wyciągnięcia!
MBH,

55

wydaje się, że obecnie nie ma różnicy między 2 funkcjami, jak pokazano w kodzie źródłowym (przypis do tego postu ):

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

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

więc jest to tylko decyzja dotycząca nazewnictwa, podobna do tej z opcją fill-parent vs match-parent.


5
świetny! dzięki. Głupie, że generowane jest ostrzeżenie dla czegoś tak kiepskiego jak zmiana nazwy funkcji.
Ktoś gdzieś

1
@ M.kazemAkhgary To nie jest pierwszy raz, gdy tracą wartość tylko po to, by zmienić imię. Zmieniono parametr „fill_parent” na „match_parent” dla wartości parametrów układu. Oba są dokładnie takie same, wskazując na tę samą wartość ..
Android developer

18

wiem, że to stare pytanie, ale mam podobną sytuację i moje rozwiązanie było

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

a następnie możesz grać z „Drawable”, stosując filtry kolorów itp


6
Działa to tylko wtedy, gdy oryginalny obraz pochodzi z zasobu.
Matt Huggins

To nawet nie odpowiada na pytanie PO.
Petro

13

Posługiwać się ViewCompat.setBackground(view, background);


12

możesz setBackgroundResource()zamiast tego użyć tjrelativeLayout.setBackgroundResource(R.drawable.back);

to działa dla mnie.


7

Teraz możesz użyć jednej z tych opcji. I tak to zadziała. Twój kolor może być kodem HEX , takim jak ten:

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

Zasób kolor , podobnie jak to:

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

Lub niestandardowy zasób xml , taki jak:

myView.setBackgroundResource(R.drawable.my_custom_background);

Mam nadzieję, że to pomoże!


6

Korzystając z Androida studio 1.5.1, otrzymałem następujące ostrzeżenia:

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

oraz skargi na wycofanie się

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

Korzystając z tego formatu, pozbyłem się obu:

    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        //noinspection deprecation
        layout.setBackgroundDrawable(drawable);
    } else {
        layout.setBackground(drawable);
    }

1

To działa dla mnie: Zobacz widok to Twój editText, spinner ... itd. I int drawable to przykład twojej trasy do rysowania (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

Miałem również ten problem, ale dokonałem obejścia za pomocą ImageView .

Spróbuj użyć RelativeLayout i dodaj w nim ImageView (szerokość i wysokość: fill_parent, scaleType: center).

Upewnij się także, że widok obrazu jest pierwszym elementem wewnątrz RelativeLayout, aby działał jako tło.


1
W rzeczywistości powinna to być tylko ifklauzula. Zobacz poprawną odpowiedź.
Pijusn

-4

Możesz także to zrobić:

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

EDYCJA: Tak jak wskazał @BlazejCzapp , lepiej unikać refleksji, jeśli potrafisz rozwiązać problem bez niego. Miałem przypadek użycia, w którym nie byłem w stanie rozwiązać bez refleksji, ale to nie jest przypadek powyżej. Więcej informacji można znaleźć na stronie http://docs.oracle.com/javase/tutorial/reflect/index.html


4
@BlazejCzapp LOL, ale ODPOWIADA na pytanie, więc nie należy go głosować bez wyjaśnienia. Kiedy powiesz dziecku, żeby czegoś nie robiło, nie mówiąc, dlaczego to zrobi;)
Fabricio

11
Nie chcę odchodzić od tematu, ale oto kilka powodów: 1. Java to język o typie statycznym - skorzystaj z kompilatora; 2. To tylko ukryte wyrażenie „if” (zaciemnia prawdziwą logikę); 3. Wydobywa działo w celu zabicia komara - ten kod wykorzystuje poważną artylerię do rozwiązania trywialnego problemu; Mam nadzieję, że to trochę uzasadnia
Błażej Czapp

Dzięki @BlazejCzapp, masz rację, miałem tutaj przypadek użycia, w którym konieczne było zrobienie czegoś takiego jak powyższy kod, ale nie należy go używać, jeśli istnieje odpowiedni sposób na poradzenie sobie z tym.
Fabricio,

2
To głupie ... nie ma absolutnie żadnego powodu, aby używać refleksji, aby to osiągnąć.
Alex Lockwood

Tak, powiedz komuś, kto zadał proste pytanie „Z czego mam korzystać?” zacznij modyfikować czas działania.
Petro
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.