71

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

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

(如果我在 XML 中设置背景可绘制对象,并且不要尝试在运行时在适配器中更改它,则填充都可以正常工作。)

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

编辑似乎其他人在这里发现了同样的问题:改变背景是否也会改变线性布局的填充?

4

5 回答 5

106

我也遇到了这个问题。大概您正在使用可绘制的 LayerList 资源?这就是我正在使用的。不幸的是,我没有找到修复它的“真正”方法,这似乎是代码中的一个错误,但我没有追究它。但是,我很幸运,因为在我的视图已经正确渲染之后我设置了“buggy”背景,所以这只是在设置背景后保存然后恢复填充值的问题,例如:

  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);
于 2011-05-04T22:12:12.147 回答
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);
}
于 2013-04-08T18:14:17.427 回答
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);
    }
}
于 2015-03-30T14:51:42.827 回答
6

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

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

于 2011-08-29T22:50:30.423 回答
-2

在 Monodroid 中,如果我发布对 SetBackgroundResource 的调用,则顶部填充和底部填充保持不变

private EditText _etInput

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

但是,左侧填充被重置为 0 !?如果未发布,则所有填充将重置为 0。

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

于 2013-09-23T18:54:10.633 回答