setBackground vs setBackgroundDrawable (Android)


258

Voglio impostare lo sfondo disegnabile di una vista. Ci sono due metodi per questo (per quanto vedo): setBackgroundesetBackgroundDrawable .

Quando lo uso setBackground, dice che è stato aggiunto nel livello API 16 ma la versione minima dell'SDK del mio progetto è 7. Presumo che non funzionerà su nulla al di sotto di 16, ho ragione? Ma quando uso setBackgroundDrawable, dice che è deprecato.

Cosa dovrei usare?


Usa: image.setImageResource (R.drawable.icon_dot1);
Coraggioso

Risposte:


403

È deprecato ma funziona ancora, quindi potresti semplicemente usarlo. Ma se vuoi essere completamente corretto, solo per la completezza di esso ... Faresti qualcosa del tipo:

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

Perché questo funzioni, devi impostare buildTarget api 16 e min build su 7 o qualcosa di simile.


4
Si lamenta ancora che setBackgroundDrawable sia deprecato. Devo davvero sopprimere i guadagni solo perché Google voleva cambiare il nome del metodo?
Charlie-Blake,

2
@ santirivera92 Sì, in alternativa puoi creare 2 progetti 1 targeting prima che si trattasse di un problema e 1 dopo. Sembra un'opzione facile? (In realtà a volte lo fa, così tante correzioni in ICS)
Warpzit

4
Ho impostato android:minSdkVersion="7" android:targetSdkVersion="17", tuttavia setBackground () viene visualizzato come errore: la chiamata richiede il livello API 16 (il minimo corrente è 7)
Jonny

20
Mi ha impedito di compilare. Ho messo il codice problematico nella sua funzione e ho disabilitato lint solo per quella funzione in questo modo. @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 il

2
@Snicolas Sì, l'IDE o Android dovrebbe essere in grado di fare questo tipo di logica per noi.
Warpzit,

111

È possibile utilizzare setBackgroundResource()invece che si trova nel livello API 1.


78
... ma solo se hai un ID risorsa e non una classe personalizzabile che hai creato!
Zordid,

non esiste un metodo per recuperare l'ID di un disegno su cui si ha un riferimento?
Poutrathor,

2
setBackgroundResource () non è un'alternativa a setBackgroundDrawable (); o setBackground () ;. Per nulla correlati, il primo ad aggiungere il disegnabile da risorse e gli altri ad aggiungere il disegnabile su misura.
MBH,

Cosa succede se devo impostare lo sfondo ripetutamente, ad esempio in Listview? setBackgroundResource(int)accetta l'ID risorsa, quindi deve gonfiare la vista ogni volta per impostare lo sfondo. Non voglio tale comportamento, supponendo che ho già gonfiato Drawable. Mi sto perdendo qualcosa?
Azizbekian

cosa succede se ho solo il disegno!?
MBH,

55

sembra che attualmente non vi sia alcuna differenza tra le 2 funzioni, come mostrato sul codice sorgente (credito per questo post ):

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

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

quindi è solo una decisione di denominazione, simile a quella con fill-parent vs match-parent.


5
grande! Grazie. È sciocco il fatto che venga generato un avviso per qualcosa di così zoppo come una rinomina di funzione.
Someone Somewhere,

1
@ M.kazemAkhgary Non è la prima volta che deprecano qualcosa solo per il cambio di nome. Avevano "fill_parent" modificato in "match_parent" per i valori dei parametri di layout. Entrambi sono esattamente la stessa cosa, puntando allo stesso valore ..
sviluppatore Android

18

So che questa è una vecchia domanda, ma ho una situazione simile e la mia soluzione era

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

e poi puoi giocare con il "Disegnabile", applicando filtri colorati, ecc


6
Funziona solo se l'immagine originale proviene da una risorsa.
Matt Huggins,

Ciò non risponde nemmeno alla domanda del PO.
Petro

13

Uso ViewCompat.setBackground(view, background);


12

potresti usare setBackgroundResource() invece ierelativeLayout.setBackgroundResource(R.drawable.back);

questo funziona per me.


7

Ora puoi utilizzare una di queste opzioni. E funzionerà in ogni caso. Il tuo colore può essere un codice esadecimale , in questo modo:

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

Una risorsa colore , come questa:

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

O una risorsa XML personalizzata , in questo modo:

myView.setBackgroundResource(R.drawable.my_custom_background);

Spero che sia d'aiuto!


6

Utilizzando Android Studio 1.5.1 ho ricevuto i seguenti avvisi:

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

e i reclami sulla deprecazione

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

Usando questo formato, mi sono liberato di entrambi:

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

1

Questo per me funziona: View view is editText, spinner ... etc. E int drawable è il tuo esempio di route drawable (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

Ho avuto anche questo problema, ma ho risolto il problema usando ImageView .

Prova a utilizzare un RelativeLayout e aggiungi un ImageView al suo interno (larghezza e altezza: fill_parent, scaleType: center).

Assicurati inoltre che l'immagine visualizzata sia il primo elemento all'interno di RelativeLayout, quindi fungerà da sfondo.


1
In realtà non avrebbe dovuto essere altro che una ifclausola. Vedi la risposta corretta
Pijusn,

-4

Puoi anche fare questo:

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

EDIT: Come sottolineato da @BlazejCzapp è preferibile evitare di usare la riflessione se riesci a risolvere il problema senza di essa. Ho avuto un caso d'uso in cui non ero in grado di risolvere senza riflessione ma questo non è il caso sopra. Per ulteriori informazioni, consultare http://docs.oracle.com/javase/tutorial/reflect/index.html


4
@BlazejCzapp LOL, ma risponde alla domanda, quindi non dovrebbe essere sottoposto a downgrade senza una spiegazione. Quando dici a un bambino di non fare qualcosa senza dire perché lo faranno;)
Fabricio,

11
Non voglio andare fuori tema, ma qui ci sono alcuni motivi: 1. Java è un linguaggio tipicamente statico - usa il compilatore; 2. Questa è solo un'istruzione if mascherata (sta offuscando la vera logica); 3. Sta tirando fuori un cannone per uccidere una zanzara - questo codice usa un'artiglieria seria per risolvere un banale problema; Spero che ciò lo giustifichi un po '
Błażej Czapp,

Grazie @BlazejCzapp, hai ragione, ho avuto un caso d'uso qui dove era necessario fare cose come il codice sopra, ma non dovrebbe essere usato se c'è un modo corretto di gestirlo.
Fabricio,

2
Questo è stupido ... non c'è assolutamente alcun motivo per usare la riflessione per raggiungere questo obiettivo.
Alex Lockwood,

Sì, dì a qualcuno che ha fatto una semplice domanda "Cosa dovrei usare?" inizia a modificare il tempo di esecuzione.
Petro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.