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ć?

Pijusn
źródło
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.

Warpzit
źródło
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.

Ludovic
źródło
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.

programista Androida
źródło
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

Jose De Gouveia
źródło
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);

krawa
źródło
12

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

to działa dla mnie.

ponnex
źródło
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!

Geraldo Neto
źródło
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);
    }
Aksel Willgert
źródło
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));
        }    
    }
użytkownik0987
źródło
0

Użyj setBackgroundResource (R.drawable.xml / png)

baburaoS
źródło
-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.

Jens-Joris Decorte
źródł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

Fabricio
źródło
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