2011-05-04 130 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