Où est passé le rembourrage, lors de la définition de l’arrière-plan?

J’ai ce problème sur mes vues EditText et Button , où je peux espacer le texte, mais lorsque je modifie l’arrière-plan avec setBackgroundDrawable ou setBackgroundResource ce remplissage est définitivement perdu.

Ce que j’ai trouvé était l’ajout d’un patch 9 en tant que ressource d’arrière-plan pour réinitialiser le remplissage – bien que ce soit intéressant si j’ai ajouté une image de patch 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 définir à nouveau.

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

J’ai pu envelopper l’élément dans une autre mise en page, dans ce cas, un FrameLayout . Cela m’a permis de modifier l’arrière-plan de FrameLayout sans détruire le remplissage, qui se trouve sur le RelativeLayout contenu.

    ... 

L’autre option consiste à le définir par programmation 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.

Je n’ai pas testé ce super bien, 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).

J’ai eu ce problème dans un TextView, alors j’ai sous-classé TextView et fait une méthode Override de la méthode TextView.setBackgroundResource(int resid) . 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 qu’il ne définisse la ressource, mais ne gêne pas la fonctionnalité d’origine de la méthode, hormis le maintien du remplissage.

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

Pour 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 simple est de définir vos rembourrages à l’intérieur d’un xml-drawable qui pointe vers le fichier-image pouvant être tiré.

Grandings

Ma solution a été d’étendre la vue (dans mon cas, un EditText ) et de remplacer les setBackgroundDrawable() et 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(); } 

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 vos vues EditText ou Button

changez simplement lib en v7: 22.1.0 dans le studio Android comme cette compilation ‘com.android.support:appcompat-v7:22.1.0’

J’utilise cette solution de contournement assez simple, je définis un accentColor dans mon style.xml comme ci-dessous

 #0288D1 

et puis j’utilise l’un des styles suivants dans mes balises Button

 style="@style/Base.Widget.AppCompat.Button.Colored" style="@style/Base.Widget.AppCompat.Button.Small" 

par exemple :

   

La plupart des réponses sont correctes mais doivent gérer correctement les parameters d’arrière-plan.

D’abord obtenir 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(); 

Ensuite, définissez le fond

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

J’ai trouvé une autre solution. Je faisais face à un 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.

En combinant toutes les solutions, 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) } 

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: