SetBackgroundResource () descarta mis atributos de diseño XML
Tengo una vista que se utiliza como artículo en un ListView
. En mi adaptador personalizado, cambio el fondo de la vista usando View.setBackgroundResource()
dependiendo de la posición del elemento en la lista. (Tengo activos separados para el primer y último elemento de la lista.)
Esto establece la imagen de fondo correcta como se espera, pero tiene el desagradable efecto secundario que todo el relleno que había establecido en la definición XML de la vista se ignora por completo.
- El hilo no interrumpe
- ¿Cómo comprobar todos los servicios en ejecución en android?
- Reproducir música de fondo en todas las actividades de la aplicación de Android
- TextureView setBackgroundColor no funciona
- Quitar fondo dibujable mediante programación en Android
(Si establezco el fondo dibujable en XML, y no trato de variarlo en tiempo de ejecución en el adaptador, el relleno todo funciona bien.)
¿Cómo puedo alterar la imagen de fondo, y conservar el relleno? ¿Es esto un error?
EDIT parece que alguien más ha encontrado el mismo problema aquí: ¿Cambiar el fondo también cambia el relleno de un LinearLayout?
- ¿Fondo vertical-rayado en XML?
- Cómo puedo configurar el fondo de todas mis actividades en styles.xml
- Dibuja el fondo de la vista personalizada desde el archivo .png en Android
- Teclado personalizado sombra clave de teclado eliminar
- Android: ¿Cómo trabajar con hilo de fondo?
- ¿Está prohibido transmitir vídeo de YouTube en segundo plano?
- Imagen de fondo de Android Widget Cambiar
- Aplicación de Android como servicio sin actividad
Me encontré con este tema también. ¿Presumiblemente está utilizando un recurso LayerList dibujable? Eso es lo que estaba usando. Desafortunadamente, no encontré una forma "real" de arreglarlo, parece un error en el código, pero no lo perseguí. Sin embargo, tuve suerte en el sentido de que estaba configurando el "buggy" de fondo después de mi vista ya se había prestado correctamente, por lo que era sólo una cuestión de guardar y restaurar 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, no tiene que utilizar los valores anteriores de relleno, también puede utilizar un valor de dimensión:
int pad = resources.getDimensionPixelSize(R.dimen.linear_layout_padding); theView.setBackgroundResource(R.drawable.entry_bg_with_image); theView.setPadding(pad, pad, pad, pad);
Agregando a lo que ha sugerido dmon, aquí es una función que sólo puede lanzar en su clase util para que no tenga que saltar a través de aros cada vez que actualiza un recurso. Esto es realmente sólo 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); }
Esto está arreglado en Lollipop, así que
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); } }
Otra solución que opté por en vez de conseguir y fijar el relleno en el código que dmon propuso no está utilizando el relleno y en lugar de usar márgenes para los elementos internos.
Dependiendo de su diseño, en realidad puede ser la misma cantidad de código XML y no requeriría ningún Java en absoluto. Se siente un poco más sucia para mí, pero no tan sucia como añadir que el código Java en todas partes.
En Monodroid, si publico la llamada a SetBackgroundResource, entonces el relleno superior y el relleno inferior permanecen inalterados
private EditText _etInput public void Disable() { _etInput.Post(() => { _etInput.SetBackgroundResource(Resource.Drawable.input_field_background_disabled); _etInput.Clickable = false; });
Sin embargo, el izquierdo-relleno se restablece a 0!? Si no se publica, todo el relleno se restablece a 0.
Pensé que esto era un hallazgo interesante vale la pena publicar sobre …
- Android descargar problemas de archivo binario
- El permiso solo se concede a la aplicación del sistema