我对我的这个问题EditText和Button意见,在这里我对他们一个很好的填充空间从文了,但是当我改变的背景,setBackgroundDrawable或者setBackgroundResource说填补处理永远失去了。
TextView下面接受的解决方案也适用于这种视图。
TextViewAPI 28(Android 9)上也存在问题。看起来它从未修复过。
我对我的这个问题EditText和Button意见,在这里我对他们一个很好的填充空间从文了,但是当我改变的背景,setBackgroundDrawable或者setBackgroundResource说填补处理永远失去了。
TextView下面接受的解决方案也适用于这种视图。
TextViewAPI 28(Android 9)上也存在问题。看起来它从未修复过。
Answers:
我发现添加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"
/>
...
另一个选项是Drawable按照上述建议设置背景后,以编程方式进行设置。只需确保计算像素以校正设备的分辨率即可。
我在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);
}
这样,它在设置资源之前就获得了项目的填充,但是除了保留填充之外,它实际上并未与方法的原始功能混淆。
尚未对此超级功能进行全面测试,但是此方法可能有用:
/**
* 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)。
向后兼容的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);
}
您可以通过使用9色块图像并在可绘制对象中定义内容区域来进行填充。 检查一下
您还可以通过xml或以编程方式在布局中设置填充
xml填充标签
android:padding
android:paddingLeft
android:paddingRight
android:paddingTop
android:paddingBottom
您可以在调用setBackgroundDrawable之后尝试通过代码手动设置填充,方法是在EditText或Button视图上调用setPadding
我的解决方案是扩展视图(在我的情况下为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();
}
结合所有解决方案,我在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)
}
只是为了解释发生了什么:
这实际上是一个功能。您可能用作背景的布局可绘制对象可以通过以下方式定义填充:
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingRight="8dp"
>
...
</layer-list>
将与新的可绘制背景一起设置此填充。没有填充时,默认值为0。
Romain Guy撰写的电子邮件中提供了更多信息:https : //www.mail-archive.com/android-developers@googlegroups.com/msg09595.html
大多数答案是正确的,但应正确处理背景设置。
首先了解您的观点
//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);
我找到了另一个解决方案。我正面临着Buttons的类似问题。最终,我添加了:
android:scaleX= "0.85"
android:scaleY= "0.85"
它为我工作。默认填充几乎相同。
这里是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>
我使用这个非常简单的解决方法,accentColor在style.xml下面的代码中定义了一个
<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" />