setBackgroundResource()放弃我的XML布局属性

我有一个用作ListView的项目的视图。 在我的自定义适配器中,使用View.setBackgroundResource()根据项目在列表中的位置更改视图的背景。 (对于列表中的第一个和最后一个项目,我有单独的资源。)

如预期的那样设置正确的背景图像,但是它具有令人讨厌的副作用,即在视图的XML定义中设置的所有填充都被完全忽略。

(如果我在XML中设置可绘制背景,并且不要在适配器的运行时改变它,那么填充一切正常。)

我怎样才能改变背景图片,并保留填充? 这是一个错误?

编辑它似乎有人已经在这里find同样的问题: 改变背景也改变了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); } 

编辑:作为替代scheme,您不必使用以前的填充值,也可以使用尺寸值:

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

添加到dmon的build议,这里是一个函数,你可以扔在你的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); } } 

我select的另一个解决scheme,而不是获得和设置填充在代码中的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。

认为这是一个值得发布有趣的发现…