J'ai ce problème sur mes vues EditText
et Button
, où j'ai un joli rembourrage pour qu'ils s'éloignent du texte, mais lorsque je change l'arrière-plan avec setBackgroundDrawable
ou, setBackgroundResource
ce remplissage est perdu à jamais.
86
TextView
et la solution acceptée ci-dessous fonctionnait également pour ce type de vue.TextView
API 28 (Android 9) également. On dirait que ça n'a jamais été corrigé.Réponses:
Ce que j'ai trouvé, c'est l'ajout d'un patch 9 en tant que ressource d'arrière-plan pour réinitialiser le rembourrage - bien que ce soit intéressant si j'ai ajouté une image de couleur ou non-9, ce n'est pas le cas. La solution consistait à enregistrer les valeurs de remplissage avant l'ajout de l'arrière-plan, puis à les redéfinir par la suite.
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);
la source
J'ai pu envelopper l'élément dans une autre mise en page, dans ce cas, un
FrameLayout
. Cela m'a permis de changer l'arrière-plan sur leFrameLayout
sans détruire le rembourrage, qui est sur le contenuRelativeLayout
.<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" /> ...
L'autre option consiste à le définir par programme après avoir défini l'arrière-plan
Drawable
comme suggéré ci-dessus. Assurez-vous simplement de calculer les pixels pour corriger la résolution de l'appareil.la source
J'ai eu ce problème dans un TextView, j'ai donc sous-classé TextView et créé une méthode Override de la
TextView.setBackgroundResource(int resid)
méthode. Comme ça:@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); }
De cette façon, il obtient le remplissage de l'élément avant de définir la ressource, mais ne gâche pas réellement la fonctionnalité d'origine de la méthode, autre que le maintien du remplissage.
la source
Je n'ai pas testé ce super minutieusement, mais cette méthode pourrait être utile:
/** * 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); }
Utilisez ceci au lieu de view.setBackgroundDrawable (Drawable).
la source
Version rétrocompatible de la réponse de 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); }
la source
Vous pouvez donner un peu de remplissage en utilisant des images à 9 patchs et en définissant la zone de contenu dans le dessin. Vérifie ça
Vous pouvez également définir le remplissage dans votre mise en page à partir de xml ou par programme
balises de remplissage xml
android:padding android:paddingLeft android:paddingRight android:paddingTop android:paddingBottom
Vous pouvez essayer de définir le remplissage manuellement à partir du code après avoir appelé setBackgroundDrawable en appelant setPadding sur votre EditText ou Button Views
la source
Pour le chercheur commun,
ajoutez simplement setPadding après setBackgroudDrawable. Lorsque vous modifiez votre dessin, vous devez à nouveau appeler setPadding.
Comme:
view.setBackgroundDrawable(backgroundDrawable); view.setPadding(x, x, x, x);
Le moyen le plus propre est de définir vos rembourrages dans un xml-drawable qui pointe vers le drawable-image-file
Grands
la source
Ma solution était d'étendre la vue (dans mon cas un EditText ) et de remplacer
setBackgroundDrawable()
et desetBackgroundResource()
méthodes:// 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(); }
la source
En combinant les solutions de toutes, j'en ai écrit une à 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) }
la source
Juste pour expliquer ce qui se passe:
C'est en fait une fonctionnalité. Les dessinables de mise en page que vous pouvez utiliser comme arrière-plans peuvent définir un remplissage de cette façon:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:paddingRight="8dp" > ... </layer-list>
Ce remplissage sera défini avec le nouvel arrière-plan dessinable. Lorsqu'il n'y a pas de remplissage, la valeur par défaut est 0.
Plus d'infos sur un email rédigé par Romain Guy: https://www.mail-archive.com/[email protected]/msg09595.html
la source
il suffit de changer lib en v7: 22.1.0 dans le studio Android comme cette compilation 'com.android.support:appcompat-v7:22.1.0'
la source
La plupart des réponses sont correctes mais doivent gérer correctement le paramètre d'arrière-plan.
Obtenez d'abord le remplissage de votre vue
//Here my view has the same padding in all directions so I need to get just 1 padding int padding = myView.getPaddingTop();
Puis définissez l'arrière-plan
//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)); }
Ensuite, définissez le remplissage de la vue avant le changement d'arrière-plan
myView.setPadding(padding, padding, padding, padding);
la source
J'ai trouvé une autre solution. J'étais confronté au problème similaire avec les boutons. Finalement, j'ai ajouté:
android:scaleX= "0.85" android:scaleY= "0.85"
cela a fonctionné pour moi. Le remplissage par défaut est presque le même.
la source
Dans mon cas, j'avais un dessinable et j'étais tellement stupide que je n'ai pas vu que les rembourrages étaient tous mis à 0 dans le xml.
la source
Voici une version améliorée de setBackgroundAndKeepPadding de cottonBallPaws. Cela maintient le remplissage même si vous appelez la méthode plusieurs fois:
/** * 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); }
Vous devez définir un identifiant de ressource via values / ids.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <item name="prev_background_padding" type="id"/> </resources>
la source
J'utilise cette solution de contournement assez simple, je définis un
accentColor
dans monstyle.xml
comme ci-dessous<item name="colorAccent">#0288D1</item>
puis j'utilise l'un des styles suivants dans mes
Button
balisesstyle="@style/Base.Widget.AppCompat.Button.Colored" style="@style/Base.Widget.AppCompat.Button.Small"
par exemple :
<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" />
la source