2011-05-04 132 views
67

我有一个视图用作ListView中的项目。在我的自定义适配器中,我使用View.setBackgroundResource()更改了视图的背景,具体取决于项目在列表中的位置。 (我为列表中的第一个和最后一个项目分开了资源)。setBackgroundResource()丢弃我的XML布局属性

这样设置了正确的背景图像,但它具有令人讨厌的副作用,即我在XML定义中设置的所有填充该观点完全被忽略。

(如果我设置在XML的背景绘制,不要试图在运行时适配器来改变它,填充一切工作正常。)

我如何可以改变背景图像,并保留填充?这是一个错误?

编辑似乎别人已经发现了同样的问题在这里:Does changing the background also change the padding of a LinearLayout?

回答

101

我就遇到了这个问题为好。据推测你正在使用可绘制的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); 
    } 

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

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

那它治愈, 谢谢。在我的情况下,可绘制的是九片PNG。 – 2011-05-04 22:23:33

+0

有趣的,那么也许它比我想象的更广泛。 – dmon 2011-05-04 22:35:43

+3

啊,的确如此。查看setBackgroundDrawable()中的视图代码(http://j.mp/kxQJIJ)。这显然是使用可绘制的填充覆盖填充。但是看一下Drawable资源文档,除了形状之外,没有任何东西支持填充,所以这可能是它悲惨失败的原因。 – dmon 2011-05-04 22:42:35

6

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

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

10

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

在MonoDroid的,如果我发布调用SetBackgroundResource,然后将顶部填充和底部填充保持不变

private EditText _etInput 

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

然而,左填充被重置为0!?如果它不贴了,那么所有的填充重置为0

思想这是一个有趣的发现值得张贴有关...

7

这是固定的棒棒糖,让

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); 
    } 
} 
+1

不,这是不固定在棒棒糖(至少不是我的股票5.1摩托G ROM) – 2016-09-09 13:59:25

+0

这是固定的,因为KitKat,所以检查应该是'Build.VERSION.SDK_INT David 2017-12-29 13:23:06