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

Gra*_*and 69 android background padding drawable layer-list

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

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

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

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

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

dmo*_*mon 106

我也遇到过这个问题.想必你正在使用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);
  }
Run Code Online (Sandbox Code Playgroud)

编辑:作为替代方案,您不必使用以前的填充值,您还可以使用维值:

  int pad = resources.getDimensionPixelSize(R.dimen.linear_layout_padding);
  theView.setBackgroundResource(R.drawable.entry_bg_with_image);
  theView.setPadding(pad, pad, pad, pad);
Run Code Online (Sandbox Code Playgroud)

  • 这绝对不是"按预期工作",当我的意思是通过使用setBackgroundResource()来改变图像的背景资源而不改变任何其他属性时,我永远不会想到它会影响元素的填充. (16认同)
  • 啊,的确如此.在setBackgroundDrawable()中查看View的代码(http://j.mp/kxQJIJ).它显然使用drawable的填充覆盖了填充.但是看看Drawable资源文档,除了形状之外什么都不支持填充,所以这可能是它失败的原因. (3认同)
  • 罗曼说:“设置图像会重置填充的原因是因为9色块图像可以对填充进行编码。如果丢失,我们会假设填充为0。” 它应该是“如果缺少** && is9Patch()**”恕我直言。 (2认同)

Bra*_*ano 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);
}
Run Code Online (Sandbox Code Playgroud)


e.s*_*kin 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Art*_*kii 6

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

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