哪里填充去,当设置背景可绘制?

我在我的EditTextButton视图上有这个问题,我有一个很好的填充,他们从文本的空间,但是当我改变背景与setBackgroundDrawablesetBackgroundResource ,填充是永远丢失。

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

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

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

没有完全testing这个超级,但是这个方法可能是有用的:

  /** * 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(Drawable)。

我在TextView中遇到了这个问题,所以我创build了TextView的子类,并创build了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); } 

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

对于普通的search者,

在setBackgroudDrawable后面添加setPadding。 当你改变drawable时,你必须再次调用setPadding。

喜欢:

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

最简洁的方法是在一个指向drawable-image-file的xml-drawable里面定义你的padding

Greatings

向后兼容版本的棉球的答案

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

我的解决scheme是扩大视图(在我的情况下一个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(); } 

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

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

XML填充标签

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

通过在EditText或Button Views上调用setPadding来调用setBackgroundDrawable之后,可以尝试从代码中手动设置填充

只是改变lib的v7:22.1.0在android工作室像这样编译'com.android.support:appcompat-v7:22.1.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" /> 

大多数的答案是正确的,但应正确处理背景设置。

首先得到你的看法的填充

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

这里有一个改进版本的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); } 

你需要通过values / ids.xml定义一个资源ID:

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