Android 设置背景 Drawable 时,padding 去哪里了?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10095196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:27:44  来源:igfitidea点击:

Where'd padding go, when setting background Drawable?

android

提问by Dandre Allison

I have this issue on my EditTextand Buttonviews, where I have a nice padding for them to space away from the text, but when I change the background with setBackgroundDrawableor setBackgroundResourcethat padding is lost forever.

我对我的这个问题EditTextButton意见,在这里我对他们一个很好的填充空间从文了,但是当我改变的背景,setBackgroundDrawable或者setBackgroundResource说填补处理永远失去了。

回答by Matt McMinn

What I found was adding a 9 patch as a background resource reset the padding - although interestingly if I added a color, or non-9 patch image, it didn't. The solution was to save the padding values before the background gets added, then set them again afterwards.

我发现添加一个 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);

回答by The Dirty Calvinist

I was able to wrap the element inside another layout, in this case, a FrameLayout. That enabled me to change the background on the FrameLayoutwithout destroying the padding, which is on the contained RelativeLayout.

我能够将元素包装在另一个布局中,在这种情况下,是一个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" 
     />
...

The other option is to set it programmatically after setting the background Drawableas suggested above. Just make sure to calculate the pixels to correct for the resolution of the device.

另一个选项是在Drawable按照上面的建议设置背景后以编程方式设置它。只需确保计算像素以校正设备的分辨率。

回答by LukeWaggoner

I had this problem in a TextView, so I subclassed TextView and made an Override method of the TextView.setBackgroundResource(int resid)method. Like this:

我在 TextView 中遇到了这个问题,因此我将 TextView 子类化并创建了该TextView.setBackgroundResource(int resid)方法的 Override方法。像这样:

@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);
}

This way, it gets the padding of the item before it sets the resource, but doesn't actually mess with the original functionality of the method, other than keeping the padding.

这样,它会在设置资源之前获取项目的填充,但实际上并不会干扰该方法的原始功能,除了保留填充。

回答by cottonBallPaws

Haven't tested this super thoroughly, but this method might be of use:

还没有彻底测试过这个超级,但这种方法可能有用:

    /**
 * 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);
}

Use this instead of view.setBackgroundDrawable(Drawable).

使用它代替 view.setBackgroundDrawable(Drawable)。

回答by Andrew G

Backward compatable version of cottonBallPaws's answer

向后兼容版本的cottonBallPaws 的答案

/** 
  * 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);
}

回答by Juan José Melero Gómez

My solution was to extend the view (in my case an EditText) and override setBackgroundDrawable()and setBackgroundResource()methods:

我的解决方案是扩展视图(在我的情况下是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();
}

回答by android developer

Combining the solutions of all, I wrote one in Kotlin:

综合大家的解决方案,我用Kotlin写了一个:

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)
}

回答by achie

You can give some padding by using 9-patch images and defining the content area in the drawable. Check this

您可以通过使用 9-patch 图像并在 drawable 中定义内容区域来提供一些填充。 检查这个

You can also set the padding in your layout from xml or programatically

您还可以从 xml 或以编程方式在布局中设置填充

xml padding tags

xml填充标签

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

You can try setting the padding manually from the code after you call the setBackgroundDrawable by calling setPadding on your EditText or Button Views

通过在 EditText 或按钮视图上调用 setPadding 调用 setBackgroundDrawable 后,您可以尝试从代码中手动设置填充

回答by Torsten

For common searcher,

对于普通搜索者,

just add setPadding after setBackgroudDrawable. When you change your drawable, you have to call setPadding again.

只需在 setBackgroudDrawable 之后添加 setPadding。当您更改 drawable 时,您必须再次调用 setPadding。

Like:

喜欢:

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

The cleanest way is define your paddings inside a xml-drawable which points to the drawable-image-file

最干净的方法是在指向 drawable-image-file 的 xml-drawable 中定义填充

Greatings

嘉年华

回答by user3104023

just change lib to v7:22.1.0 in android studio like this compile 'com.android.support:appcompat-v7:22.1.0'

只需在 android studio 中将 lib 更改为 v7:22.1.0,就像这样 compile 'com.android.support:appcompat-v7:22.1.0'