2012-04-10 54 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) 
}