SetBackgroundResource () отбрасывает мои атрибуты макета XML

У меня есть представление, которое используется как элемент в ListView . В моем пользовательском адаптере я меняю фон представления с помощью View.setBackgroundResource() зависимости от позиции элемента в списке. (У меня есть отдельные активы для первого и последнего элементов в списке.)

Это задает правильное фоновое изображение, как и ожидалось, но имеет неприятный побочный эффект, что все дополнения, которые я установил в определении XML представления, полностью игнорируются.

(Если я устанавливаю фоновый чертеж в XML и не пытаюсь изменить его во время выполнения в адаптере, то отступы все отлично работают.)

Как изменить фоновое изображение и сохранить отступы? Это ошибка?

EDIT кажется, что кто-то другой нашел ту же проблему здесь: меняет ли фон фон и добавляет LinearLayout?

Solutions Collecting From Web of "SetBackgroundResource () отбрасывает мои атрибуты макета XML"

Я столкнулся с этим вопросом. Предположительно, вы используете ресурс LayerList? Это то, что я использовал. К сожалению, я не нашел «реального» способа его исправления, это похоже на ошибку в коде, но я не преследовал ее. Тем не менее, мне повезло в том смысле, что я устанавливал «багги» фон после того, как мой взгляд уже был обработан правильно, поэтому это было просто вопрос сохранения, а затем восстановление значений заполнения после того, как фон установлен, например:

  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: в качестве альтернативы вам не нужно использовать предыдущие значения отступов, вы также можете использовать значение измерения:

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

Добавляя к тому, что предложил dmon, вот функция, которую вы можете просто ввести в свой класс util, чтобы вам не приходилось перепрыгивать через обручи каждый раз при обновлении ресурса. Это действительно просто его код, завернутый в функцию.

 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); } 

Это зафиксировано в Lollipop, поэтому

 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); } } 

Еще одно решение, которое я выбрал вместо того, чтобы получать и устанавливать дополнение в коде, предложенном dmon, не использует заполнение и вместо этого использует поля для внутренних элементов.

В зависимости от вашего макета, на самом деле это может быть одинаковое количество XML-кода и вообще не требует никакой Java. Это кажется мне немного грязнее, но не так грязно, как добавление кода Java во всем мире.

В Monodroid, если я отправляю вызов SetBackgroundResource, то верхнее и нижнее заполнение остаются неизменными

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

Однако, левое заполнение сбрасывается на 0!? Если он не отправлен, то все дополнения будут сброшены на 0.

Думал, что это интересная находка, посвященная …