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

时间:2011-05-04 22:01:09

标签: android background drawable padding layer-list

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

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

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

如何更改背景图像并保留填充?这是一个错误吗?

编辑似乎其他人在此处发现了同样的问题:Does changing the background also change the padding of a LinearLayout?

5 个答案:

答案 0 :(得分:104)

我也遇到了这个问题。想必你正在使用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);

答案 1 :(得分:11)

添加到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);
}

答案 2 :(得分:7)

这已在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);
    }
}

答案 3 :(得分:6)

我选择的另一种解决方案,而不是在dmon提出的代码中获取和设置填充,而不是使用填充,而是使用内部元素的边距。

根据您的布局,它实际上可能是相同数量的XML代码,根本不需要任何Java。对我来说感觉有点脏,但不像在任何地方添加Java代码那么脏。

答案 4 :(得分:-1)

在Monodroid中,如果我将调用发布到SetBackgroundResource,那么顶部填充和底部填充保持不变

private EditText _etInput

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

但是,左边填充会重置为0!如果未发布,则所有填充都将重置为0.

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