setBackgroundResource () отбрасывает мои атрибуты макета XML
у меня есть представление, которое используется в качестве элемента в ListView
. В моем пользовательском адаптере я изменяю фон представления с помощью View.setBackgroundResource()
в зависимости от позиции элемента в списке. (У меня есть отдельные активы для первого и последнего элементов в списке.)
Это устанавливает правильное фоновое изображение, как ожидалось, но у него есть неприятный побочный эффект, что все отступы, которые я установил в XML-определении представления, полностью игнорируются.
(Если я устанавливаю фон, который можно нарисовать в XML, и не пытайтесь изменить его во время выполнения в адаптере, заполнение все работает нормально.)
Как я могу изменить фоновое изображение и сохранить отступы? Это ошибка?
EDIT кажется, кто-то еще нашел ту же проблему здесь: изменение фона также изменяет заполнение LinearLayout?
5 ответов:
я столкнулся с этой проблемой, а также. Предположительно вы используете ресурс LayerList drawable? Это то, что я использовал. К сожалению, я не нашел "реального" способа исправить это, это похоже на ошибку в коде, но я не преследовал его. Тем не менее, мне повезло в том смысле, что я устанавливал фон "багги" после того, как мой вид уже был правильно отображен, поэтому это был просто вопрос сохранения, а затем восстановления значений заполнения после установки фона, например:
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); }
изменить: Как альтернативно, вам не нужно использовать предыдущие значения заполнения, вы также можете использовать значение измерения:
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); }
это исправлено в леденец, так что
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.
подумал, что это интересная находка, о которой стоит написать ...