2012-04-10 56 views
71

我在我的EditTextButton視圖中有這個問題,在這裏我有一個很好的填充位置,讓他們遠離文本,但是當我用setBackgroundDrawablesetBackgroundResource更改背景時,填充會永久丟失。何時填充去,當設置背景可繪製?

+2

這個問題是固定在Android 4.4的奇巧 – 2015-04-18 14:52:32

+1

在我的Nexus 5 4.4.3這個問題仍然發生。 – 2015-07-24 09:27:29

+1

我相信它只是在Lollipop(5.0) – 2016-04-13 11:33:34

回答

0

您可以通過使用9補丁圖像並定義drawable中的內容區域來填充一些填充。 Check this

您還可以設置填充在佈局從XML或編程

XML填充標籤

android:padding 
android:paddingLeft 
android:paddingRight 
android:paddingTop 
android:paddingBottom 

你可以嘗試從代碼中手動設置填充您可以通過調用調用setBackgroundDrawable後您的EditText或按鈕視圖上的setPadding

+0

我已經爲XML中的EditText和Button定義了padding,並且它顯示的很好,直到我更改Drawable,然後我失去了填充。 – 2012-04-10 21:45:44

+0

它可能會根據您以前和新的drawable之間內容區域的變化而改變。你有沒有嘗試增加填充,看看它是否給予任何填充。 – achie 2012-04-10 21:50:40

+1

好的抱歉,我應該完全讀你的問題。由於您正在更改backgrounddrawable,因此可能會刪除填充。我不確定是這樣。但是,如果是這種情況,您可以嘗試通過調用setPadding在您的EditText或Button Views上調用setBackgroundDrawable來從代碼中手動設置填充。 – achie 2012-04-10 21:54:34

11

我能夠將該元素封裝在另一個佈局中,在本例中爲FrameLayout。這使我可以更改FrameLayout的背景,而不會破壞包含RelativeLayout上的填充。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:id="@+id/commentCell" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:background="@drawable/comment_cell_bg_single" > 

    <RelativeLayout android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:padding="20dp" > 

    <ImageView android:id="@+id/sourcePic" 
       android:layout_height="75dp" 
       android:layout_width="75dp" 
       android:padding="5dp" 
       android:background="@drawable/photoframe" 
    /> 
... 

另一種選擇是,以設置背景Drawable如上面所建議的編程之後進行設置。只要確保計算像素以糾正設備的分辨率即可。

9

還沒有徹底測試此超,但這種方法可能是有用的:

/** 
* Sets the background for a view while preserving its current padding. If the background drawable 
* has its own padding, that padding will be added to the current padding. 
* 
* @param view View to receive the new background. 
* @param backgroundDrawable Drawable to set as new background. 
*/ 
public static void setBackgroundAndKeepPadding(View view, Drawable backgroundDrawable) { 
    Rect drawablePadding = new Rect(); 
    backgroundDrawable.getPadding(drawablePadding); 
    int top = view.getPaddingTop() + drawablePadding.top; 
    int left = view.getPaddingLeft() + drawablePadding.left; 
    int right = view.getPaddingRight() + drawablePadding.right; 
    int bottom = view.getPaddingBottom() + drawablePadding.bottom; 

    view.setBackgroundDrawable(backgroundDrawable); 
    view.setPadding(left, top, right, bottom); 
} 

使用這個代替view.setBackgroundDrawable的(可繪製)。

+1

如果視圖已經有填充,在多次調用此函數後,背景圖片會移動因爲你增加查看填充與以前的值 – iBog 2013-02-21 12:18:43

+0

是的,如果填充將要改變幾次,你會採取不同的方法。可能跟蹤原始填充與可填充填充。 – cottonBallPaws 2013-02-24 17:31:26

82

我發現增加了一個9補丁作爲背景資源重置填充 - 雖然有趣的是,如果我添加了顏色或非9補丁圖像,它沒有。解決方案是在添加背景之前保存填充值,然後再設置它們。

private EditText value = (EditText) findViewById(R.id.value); 

int pL = value.getPaddingLeft(); 
int pT = value.getPaddingTop(); 
int pR = value.getPaddingRight(); 
int pB = value.getPaddingBottom(); 

value.setBackgroundResource(R.drawable.bkg); 
value.setPadding(pL, pT, pR, pB); 
+1

歡呼的隊友!它很簡單,像魅力一樣工作 – 2013-04-17 15:28:33

+0

對於任何使用這種方法遇到問題的人,一定要調用getPadding ...在調用setBackgroundResource()之前。 – 2013-12-31 03:36:09

+0

看來這種方式不會保留可繪製的填充? – 2014-02-13 17:51:53

8

我曾在一個TextView這個問題,所以我子類的TextView並提出了TextView.setBackgroundResource(int resid)方法的覆蓋方法。就像這樣:

@Override 
public void setBackgroundResource(int resid) { 
    int pl = getPaddingLeft(); 
    int pt = getPaddingTop(); 
    int pr = getPaddingRight(); 
    int pb = getPaddingBottom(); 

    super.setBackgroundResource(resid); 

    this.setPadding(pl, pt, pr, pb); 
} 

這樣一來,它得到該項目的填充它集資源之前,但實際上並沒有亂用方法的原始功能,不是保持填充等。

-1

這裏是一個改進版本的cottonBallPaws的setBackgroundAndKeepPadding。這維持了即使你調用該方法多次填充:

/** 
* Sets the background for a view while preserving its current padding. If the background drawable 
* has its own padding, that padding will be added to the current padding. 
*/ 
public static void setBackgroundAndKeepPadding(View view, Drawable backgroundDrawable) { 

    Rect drawablePadding = new Rect(); 
    backgroundDrawable.getPadding(drawablePadding); 

    // Add background padding to view padding and subtract any previous background padding 
    Rect prevBackgroundPadding = (Rect) view.getTag(R.id.prev_background_padding); 
    int left = view.getPaddingLeft() + drawablePadding.left - 
      (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.left); 
    int top = view.getPaddingTop() + drawablePadding.top - 
      (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.top); 
    int right = view.getPaddingRight() + drawablePadding.right - 
      (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.right); 
    int bottom = view.getPaddingBottom() + drawablePadding.bottom - 
      (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.bottom); 
    view.setTag(R.id.prev_background_padding, drawablePadding); 

    view.setBackgroundDrawable(backgroundDrawable); 
    view.setPadding(left, top, right, bottom); 
} 

你需要通過定義值的資源ID/ids.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <item name="prev_background_padding" type="id"/> 
</resources> 
1

對於普通搜索,

剛setBackgroudDrawable後添加setPadding。當你改變drawable時,你必須再次調用setPadding。

像:

view.setBackgroundDrawable(backgroundDrawable); 
view.setPadding(x, x, x, x); 

最徹底的方法是定義XML抽拉它指向繪製圖像文件內的墊襯

Greatings

+0

在XML中設置填充是非常好的主意 – 2016-02-24 16:39:19

0

只是改變LIB到V7:22.1 .0在android studio中這樣編譯'com.android.support:appcompat-v7:22.1.0'

+1

我在這裏找到它https://code.google.com/p/android/issues/detail?id=77982 – user3104023 2015-06-29 09:26:05

2

向後兼容版本的cottonBallPaws's回答

/** 
    * Sets the background for a view while preserving its current  padding. If the background drawable 
    * has its own padding, that padding will be added to the current padding. 
* 
* @param view View to receive the new background. 
* @param backgroundDrawable Drawable to set as new background. 
*/ 
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
@SuppressWarnings("deprecation") 
public static void setBackgroundAndKeepPadding(View view, Drawable backgroundDrawable) { 
    Rect drawablePadding = new Rect(); 
    backgroundDrawable.getPadding(drawablePadding); 
    int top = view.getPaddingTop() + drawablePadding.top; 
    int left = view.getPaddingLeft() + drawablePadding.left; 
    int right = view.getPaddingRight() + drawablePadding.right; 
    int bottom = view.getPaddingBottom() + drawablePadding.bottom; 

    int sdk = android.os.Build.VERSION.SDK_INT; 
    if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { 
     view.setBackgroundDrawable(backgroundDrawable); 
    } else { 
     view.setBackground(backgroundDrawable); 
    } 
    view.setPadding(left, top, right, bottom); 
} 
0

我用這個很簡單的解決方法我在style.xml定義accentColor像下面

<item name="colorAccent">#0288D1</item> 

,然後我用我的Button標籤下面的款式之一

style="@style/Base.Widget.AppCompat.Button.Colored" 
style="@style/Base.Widget.AppCompat.Button.Small" 

例如:

<Button 
    android:id="@+id/btnLink" 
    style="@style/Base.Widget.AppCompat.Button.Colored" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@id/tvDescription" 
    android:textColor="@color/textColorPrimary" 
    android:text="Visit Website" /> 

<Button 
    android:id="@+id/btnSave" 
    style="@style/Base.Widget.AppCompat.Button.Small" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@id/tvDescription" 
    android:layout_toRightOf="@id/btnLink" 
    android:textColor="@color/textColorPrimaryInverse" 
    android:text="Save" /> 
0

大多數答案都是正確的,但應該正確處理背景設置。

首先獲得您的視圖的填充

//Here my view has the same padding in all directions so I need to get just 1 padding 
int padding = myView.getPaddingTop(); 

然後設置背景

//If your are supporting lower OS versions make sure to verify the version 
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { 
    //getDrawable was deprecated so use ContextCompat        
    myView.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.bg_accent_underlined_white)); 
} else { 
    myView.setBackground(ContextCompat.getDrawable(context, R.drawable.bg_accent_underlined_white)); 
} 

然後設置填充視圖的背景變化

myView.setPadding(padding, padding, padding, padding); 
1

我的解決辦法之前,有擴大看法(在我的情況下,一個EditText )和覆蓋setBackgroundDrawable()setBackgroundResource()方法:

// Stores padding to avoid padding removed on background change issue 
public void storePadding(){ 
    mPaddingLeft = getPaddingLeft(); 
    mPaddingBottom = getPaddingTop(); 
    mPaddingRight = getPaddingRight(); 
    mPaddingTop = getPaddingBottom(); 
} 

// Restores padding to avoid padding removed on background change issue 
private void restorePadding() { 
    this.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); 
} 

@Override 
public void setBackgroundResource(@DrawableRes int resId) { 
    storePadding(); 
    super.setBackgroundResource(resId); 
    restorePadding(); 
} 

@Override 
public void setBackgroundDrawable(Drawable background) { 
    storePadding(); 
    super.setBackgroundDrawable(background); 
    restorePadding(); 
} 
0

我發現了另一個解決方案。 我正面臨與按鈕類似的問題。 最後,我說:

android:scaleX= "0.85" 
android:scaleY= "0.85" 

它爲我工作。默認的填充幾乎相同。

0

結合所有的解決方案,我寫了一個在科特林:

fun View.setViewBackgroundWithoutResettingPadding(@DrawableRes backgroundResId: Int) { 
    val paddingBottom = this.paddingBottom 
    val paddingStart = ViewCompat.getPaddingStart(this) 
    val paddingEnd = ViewCompat.getPaddingEnd(this) 
    val paddingTop = this.paddingTop 
    setBackgroundResource(backgroundResId) 
    ViewCompat.setPaddingRelative(this, paddingStart, paddingTop, paddingEnd, paddingBottom) 
} 

fun View.setViewBackgroundWithoutResettingPadding(background: Drawable?) { 
    val paddingBottom = this.paddingBottom 
    val paddingStart = ViewCompat.getPaddingStart(this) 
    val paddingEnd = ViewCompat.getPaddingEnd(this) 
    val paddingTop = this.paddingTop 
    ViewCompat.setBackground(this, background) 
    ViewCompat.setPaddingRelative(this, paddingStart, paddingTop, paddingEnd, paddingBottom) 
}