setBackground vs setBackgroundDrawable (Android)


258

Quiero establecer el fondo dibujable de una vista. Hay dos métodos para esto (por lo que veo): setBackgroundy setBackgroundDrawable.

Cuando lo uso setBackground, dice que se ha agregado en el nivel 16 de API pero la versión mínima del SDK de mi proyecto es 7. Asumo que no funcionará en nada por debajo de 16, ¿estoy en lo cierto? Pero cuando uso setBackgroundDrawable, dice que está en desuso.

¿Qué se supone que debo usar?


Uso: image.setImageResource (R.drawable.icon_dot1);
Valiente

Respuestas:


403

Está en desuso pero aún funciona, así que puedes usarlo. Pero si quieres ser completamente correcto, solo por la integridad de esto ... Harías algo como lo siguiente:

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

Para que esto funcione, debe establecer buildTarget api 16 y min build en 7 o algo similar.


44
Todavía se queja de que setBackgroundDrawable está en desuso. ¿Realmente tengo que suprimir las advertencias solo porque Google quería cambiar el nombre del método?
Charlie-Blake

2
@ santirivera92 Sí, puede crear 2 proyectos, 1 focalización antes de que fuera un problema y 1 después. ¿Suena eso como una opción fácil? (En realidad a veces lo hace, muchas correcciones en ICS)
Warpzit

44
Configuré android:minSdkVersion="7" android:targetSdkVersion="17", sin embargo, setBackground () sale como error: la llamada requiere el nivel 16 de API (el minimo actual es 7)
Jonny

20
Me impidió compilar. Puse el código problemático en su propia función y deshabilité la pelusa solo para esa función como esta. @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 Sí, el IDE o Android deberían poder hacer este tipo de lógica por nosotros.
Warpzit

111

En su setBackgroundResource()lugar, puede usar el que está en el nivel 1 de API.


78
... pero solo si obtuvo una identificación de recursos y no una clase dibujable personalizada que creó.
Zordid

¿No hay ningún método para recuperar la identificación de un dibujo en el que tiene una referencia?
Poutrathor

2
setBackgroundResource () no es una alternativa a setBackgroundDrawable (); o setBackground () ;. No está relacionado en absoluto, el primero en agregar recursos extraíbles y los otros en agregar elementos personalizados.
MBH

¿Qué pasa si tengo que establecer el fondo repetidamente, digamos en la vista de lista? setBackgroundResource(int)acepta la identificación del recurso, por lo tanto, debe inflar la vista cada vez para establecer el fondo. No quiero ese comportamiento, suponiendo que ya haya inflado Drawable. ¿Me estoy perdiendo de algo?
azizbekian

¿Qué pasa si solo tengo el dibujable?
MBH

55

Parece que actualmente no hay diferencia entre las 2 funciones, como se muestra en el código fuente (crédito a esta publicación ):

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

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

así que es solo una decisión de denominación, similar a la de fill-parent vs match-parent.


55
¡Excelente! Gracias. Es tonto que se genere una advertencia para algo tan cojo como un cambio de nombre de función.
Alguien en alguna parte

1
@ M.kazemAkhgary No es la primera vez que desprecian algo solo por cambiar de nombre. Tenían "fill_parent" cambiado a "match_parent" para los valores de los parámetros de diseño. Ambos son exactamente lo mismo, apuntando al mismo valor ...
desarrollador de Android

18

Sé que esta es una vieja pregunta, pero tengo una situación similar, y mi solución fue

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

y luego puedes jugar con el "Drawable", aplicando filtros de color, etc.


66
Esto solo funciona si la imagen original proviene de un recurso.
Matt Huggins

Esto ni siquiera responde la pregunta del OP.
Petro

13

Utilizar ViewCompat.setBackground(view, background);


12

podría usar setBackgroundResource()en su lugar, es decirrelativeLayout.setBackgroundResource(R.drawable.back);

esto funciona para mi


7

Ahora puede usar cualquiera de esas opciones. Y va a funcionar en cualquier caso. Su color puede ser un código HEX , como este:

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

Un recurso de color , como este:

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

O un recurso xml personalizado , así:

myView.setBackgroundResource(R.drawable.my_custom_background);

¡Espero eso ayude!


6

Usando Android Studio 1.5.1 recibí las siguientes advertencias:

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

y las quejas sobre deprecación

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

Usando este formato, me deshice de ambos:

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

1

Esto funciona para mí: la vista de vista es su editText, spinner ... etc. E int drawable es su ejemplo de ruta dibujable (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

También tuve este problema, pero hice una solución usando ImageView .

Intente usar un RelativeLayout y agregue un ImageView dentro de él (ancho y alto: fill_parent, scaleType: center).

También asegúrese de que la vista de imagen sea el primer elemento dentro de RelativeLayout, para que actúe como fondo.


1
En realidad, no debería haber sido más que una ifcláusula. Ver la respuesta correcta.
Pijusn

-4

También puedes hacer esto:

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

EDITAR: tal como lo señaló @BlazejCzapp , es preferible evitar usar la reflexión si puede resolver el problema sin ella. Tuve un caso de uso donde no pude resolverlo sin reflexionar, pero ese no es el caso anterior. Para obtener más información, visite http://docs.oracle.com/javase/tutorial/reflect/index.html


44
@BlazejCzapp LOL, pero responde la pregunta, por lo que no se debe votar sin una explicación. Cuando le dices a un niño que no haga algo sin decirle por qué lo hará;)
Fabricio

11
No quiero desviarme del tema, pero aquí hay algunas razones: 1. Java es un lenguaje estáticamente tipado; utilice el compilador; 2. Esto es solo una declaración if disfrazada (está ofuscando la lógica verdadera); 3. Está sacando un cañón para matar un mosquito: este código está usando una artillería seria para resolver un problema trivial; Espero que eso lo justifique un poco
Błażej Czapp

Gracias @BlazejCzapp, tienes razón, tuve un caso de uso aquí donde era necesario hacer cosas como el código anterior, pero no debería usarse si hay una manera adecuada de manejar esto.
Fabricio

2
Esto es tonto ... no hay absolutamente ninguna razón para usar la reflexión para lograr esto.
Alex Lockwood

Sí, dígale a alguien que hizo una pregunta simple "¿Qué se supone que debo usar?" comenzar a modificar el tiempo de ejecución.
Petro
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.