2011-05-04 9 views
67

Tengo una visión que se utiliza como un elemento de una ListView. En mi adaptador personalizado, cambio el fondo de la vista utilizando View.setBackgroundResource() dependiendo de la posición del elemento de la lista. (Tengo activos separados para el primer y el último elemento de la lista.)setBackgroundResource() descarta atributos XML mi diseño

Establece la imagen de fondo correcta como se esperaba, pero tiene el desagradable efecto secundario que todo el relleno que establecí en la definición XML de la vista es completamente ignorada

(Si fijo el dibujable fondo en el XML, y no trato de variar en tiempo de ejecución en el adaptador, todo el relleno funciona bien.)

Cómo puede alterar I la imagen de fondo, y retener el relleno? ¿Es esto un error?

EDITAR parece que alguien ha encontrado el mismo problema aquí: Does changing the background also change the padding of a LinearLayout?

Respuesta

101

me encontré con este problema también. Presumiblemente, ¿está utilizando un recurso dibujable de LayerList? Eso es lo que estaba usando. Desafortunadamente, no encontré una forma "real" de solucionarlo, parece un error en el código, pero no lo busqué. Sin embargo, tuve la suerte en el sentido de que yo estaba sentado al fondo "con errores" después de mi vista ya se había rendido adecuadamente, por lo que era sólo una cuestión de ahorro de entonces la restauración de los valores de relleno después de que el fondo se establece, por ejemplo:

if(condition) { 
    int bottom = theView.getPaddingBottom(); 
    int top = theView.getPaddingTop(); 
    int right = theView.getPaddingRight(); 
    int left = theView.getPaddingLeft(); 
    theView.setBackgroundResource(R.drawable.entry_bg_with_image); 
    theView.setPadding(left, top, right, bottom); 
    } 

EDIT: Como alternativa, usted no tiene que utilizar los valores anteriores de relleno, también se puede utilizar un valor de cota:

int pad = resources.getDimensionPixelSize(R.dimen.linear_layout_padding); 
    theView.setBackgroundResource(R.drawable.entry_bg_with_image); 
    theView.setPadding(pad, pad, pad, pad); 
+0

Eso lo cura , Gracias. En mi caso, el dibujable es un PNG de nueve parches. –

+0

Interesante, entonces tal vez esté más extendido de lo que pensaba. – dmon

+3

Ah, de hecho lo es. Echar un vistazo al código de la Vista (http://j.mp/kxQJIJ), en setBackgroundDrawable(). Está sobrescribiendo claramente el relleno usando el relleno del dibujo.Pero echando un vistazo a la documentación del recurso Drawable, nada es compatible con el relleno, excepto las formas, por lo que podría ser por qué falla miserablemente. – dmon

6

Otra solución que he optado por lugar de obtener y configuración de relleno en el código que dmon propuso no está usando relleno y en su lugar utiliza márgenes para elementos internos.

Dependiendo de su diseño, que en realidad puede ser la misma cantidad de código XML y no requeriría ninguna de Java en absoluto. Me parece un poco más sucio, pero no tan sucio como agregar ese código Java en todas partes.

10

Añadiendo a lo DMON ha sugerido, aquí es una función sólo puede lanzar en su clase util por lo que no tiene que pasar por el aro cada vez que se actualiza un recurso. Esto es realmente solo su código envuelto en una función.

public static void updateBackgroundResourceWithRetainedPadding(View view, int resourceID) 
{ 
    int bottom = view.getPaddingBottom(); 
    int top = view.getPaddingTop(); 
    int right = view.getPaddingRight(); 
    int left = view.getPaddingLeft(); 
    view.setBackgroundResource(resourceID); 
    view.setPadding(left, top, right, bottom); 
} 
-1

En Monodroid, si publicar el llamado a SetBackgroundResource, entonces el-relleno superior e inferior-padding permanece inalterada

private EditText _etInput 

public void Disable() 
{ 
    _etInput.Post(() => { 
     _etInput.SetBackgroundResource(Resource.Drawable.input_field_background_disabled); 
     _etInput.Clickable = false; 
}); 

Sin embargo, la izquierda-padding se restablece a 0? Si no se ha publicado, entonces todo el relleno se pone a 0.

pensamiento que se trata de un hallazgo interesante, vale la pena publicar sobre ...

7

Este se fija en Lollipop, por lo

public static void setBackgroundResource(@NonNull View view, @DrawableRes int resId) { 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 
     int paddingTop = view.getPaddingTop(); 
     int paddingLeft = view.getPaddingLeft(); 
     int paddingRight = view.getPaddingRight(); 
     int paddingBottom = view.getPaddingBottom(); 
     view.setBackgroundResource(resId); 
     view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); 
    } else { 
     view.setBackgroundResource(resId); 
    } 
} 
+1

No, esto no está solucionado en Lollipop (al menos no en mi stock 5.1 Moto G ROM) –

+0

Esto está arreglado desde KitKat, por lo que el cheque debería ser 'Build.VERSION.SDK_INT David

Cuestiones relacionadas