У меня есть эта проблема с моими представлениями EditText
и Button
, где у меня есть хороший отступ, чтобы они располагались вдали от текста, но когда я меняю фон с помощью setBackgroundDrawable
или setBackgroundResource
это отступы теряются навсегда.
86
TextView
и принятое ниже решение также работало для этого типа представления.TextView
API 28 (Android 9). Похоже, это так и не было исправлено.Ответы:
Я обнаружил, что добавление патча 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 и создал метод Override для этого
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); }
Таким образом, он получает заполнение элемента до того, как он устанавливает ресурс, но на самом деле не вмешивается в исходную функциональность метода, кроме сохранения заполнения.
источник
Не тестировал это очень тщательно, но этот метод может пригодиться:
/** * 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 патчами и определив область содержимого в Drawable. Проверь это
Вы также можете установить отступы в своем макете из xml или программно
теги заполнения xml
android:padding android:paddingLeft android:paddingRight android:paddingTop android:paddingBottom
Вы можете попробовать установить заполнение вручную из кода после вызова setBackgroundDrawable, вызвав setPadding в EditText или в представлениях кнопок.
источник
Для обычного поисковика,
просто добавьте setPadding после setBackgroudDrawable. Когда вы меняете свой drawable, вам нужно снова вызвать setPadding.
Подобно:
view.setBackgroundDrawable(backgroundDrawable); view.setPadding(x, x, x, x);
Самый чистый способ - определить ваши отступы внутри xml-drawable, который указывает на файл drawable-image
Приветствия
источник
Мое решение состояло в том, чтобы расширить представление (в моем случае 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(); }
источник
Объединив все решения, я написал одно на Котлине:
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.
Дополнительная информация из электронного письма, написанного Роменом Гаем: https://www.mail-archive.com/android-developers@googlegroups.com/msg09595.html
источник
просто измените lib на v7: 22.1.0 в студии Android, например, скомпилируйте com.android.support:appcompat-v7:22.1.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);
источник
Нашел другое решение. Я столкнулся с аналогичной проблемой с кнопками. В конце концов, я добавил:
android:scaleX= "0.85" android:scaleY= "0.85"
у меня это сработало. Заполнение по умолчанию почти такое же.
источник
В моем случае у меня была возможность рисования, и я был настолько глуп, что не видел, чтобы все отступы были установлены на 0 в xml.
источник
Здесь улучшенная версия setBackgroundAndKeepPadding от 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. */ 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:
<?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" />
источник