我有一个用作ListView
项目的视图。在我的自定义适配器中,我使用View.setBackgroundResource()
更改视图的背景,具体取决于项目在列表中的位置。 (我对列表中的第一个和最后一个项目有单独的资产。)
这会按预期设置正确的背景图像,但它具有令人讨厌的副作用,即我在视图的XML定义中设置的所有填充都被完全忽略。
(如果我在XML中设置了可绘制的背景,并且不要尝试在适配器的运行时改变它,那么填充一切正常。)
如何更改背景图像并保留填充?这是一个错误吗?
编辑似乎其他人在此处发现了同样的问题:Does changing the background also change the padding of a LinearLayout?
答案 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.
认为这是一个值得发布的有趣发现......