Modification de la couleur de la ligne de fond EditText avec appcompat v7

J’utilise appcompat v7 pour obtenir l’apparence cohérente sur Android 5 et moins. Cela fonctionne plutôt bien. Cependant, je ne peux pas comprendre comment modifier la couleur de la ligne inférieure et la couleur d’accentuation pour EditTexts. C’est possible?

J’ai essayé de définir un android:editTextStyle personnalisé android:editTextStyle (cf. ci-dessous) mais je n’ai réussi à changer que la couleur d’arrière-plan ou la couleur du texte mais pas la ligne du bas ni la couleur d’accent. Existe-t-il une valeur de propriété spécifique à utiliser? dois-je utiliser une image personnalisable à travers l’ android:background propriété d’ android:background ? n’est-il pas possible de spécifier une couleur en hexa?

   @style/Widget.App.EditText   ???  

Selon les sources d’API Android 21, les EditTexts avec la conception matérielle semblent utiliser colorControlActivated et colorControlNormal . Par conséquent, j’ai essayé de remplacer ces propriétés dans la définition de style précédente, mais cela n’a aucun effet. Appcompat ne l’utilise probablement pas. Malheureusement, je ne trouve pas les sources de la dernière version d’appcompat avec la conception matérielle.

Enfin, j’ai trouvé une solution. Il consiste simplement à colorControlActivated la valeur de colorControlActivated , colorControlHighlight et colorControlNormal dans la définition du thème de votre application et non dans votre style edittext. Ensuite, pensez à utiliser ce thème pour toute activité que vous désirez. Voici un exemple:

  

Je pensais que cela nécessitait une réponse au cas où quelqu’un voudrait changer un seul edittext. Je le fais comme ça:

 editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP); 

Bien que la solution de Laurents soit correcte, elle présente certains inconvénients, tels que décrits dans les commentaires, car non seulement la ligne inférieure de EditText est teintée, mais également le bouton Précédent de la Toolbar , les EditText , etc.

Heureusement, la version v22.1 de appcompat-v7 introduit de nouvelles possibilités. Il est maintenant possible d’atsortingbuer un thème spécifique à une seule vue. Directement du Changelog :

Utilisation obsolète de l’application: thème pour la barre d’outils de style. Vous pouvez maintenant utiliser Android: thème pour les barres d’outils sur tous les appareils de niveau 7 et supérieur d’API et Android: support de thème pour tous les widgets sur les appareils de niveau 11 et supérieur de l’API.

Ainsi, au lieu de définir la couleur souhaitée dans un thème global, nous en créons un nouveau et l’ EditText uniquement à EditText .

Exemple:

  

  

Pour référence. Cela peut être changé dans XML en utilisant:

 android:backgroundTint="@color/blue" 

Voici la solution pour les API <21 et supérieures

 Drawable drawable = yourEditText.getBackground(); // get current EditText drawable drawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP); // change the drawable color if(Build.VERSION.SDK_INT > 16) { yourEditText.setBackground(drawable); // set the new drawable to EditText }else{ yourEditText.setBackgroundDrawable(drawable); // use setBackgroundDrawable because setBackground required API 16 } 

entrer la description de l'image ici

J’espère que ça aide

La réponse acceptée est un peu plus par style, mais la solution la plus efficace consiste à append l’atsortingbut colorAccent dans votre style AppTheme, comme ceci:

   

L'atsortingbut colorAccent est utilisé pour la coloration du widget dans toute l'application et doit donc être utilisé pour la cohérence

Si vous utilisez appcompat-v7:22.1.0+ vous pouvez utiliser DrawableCompat pour teinter vos widgets

  public static void tintWidget(View view, int color) { Drawable wrappedDrawable = DrawableCompat.wrap(view.getBackground()); DrawableCompat.setTint(wrappedDrawable.mutate(), getResources().getColor(color)); view.setBackgroundDrawable(wrappedDrawable); } 

Utilisation:

  

Cela supportera les appareils pré-Lollipop non seulement +21

   

Une solution rapide à votre problème consiste à rechercher dans votre package / build / intermediates / exploded-aar / com.android.support / appcompat-v7 / res / drawable / pour abc_edit_text_material.xml et à copier ce fichier xml dans votre dossier à dessiner. Ensuite, vous pouvez changer la couleur des 9 fichiers de patch à l’intérieur de ce sélecteur, afin de correspondre à vos préférences.

Voici une partie du code source de TextInputLayout dans la bibliothèque de conception du support ( UPDATED pour la version 23.2.0 ), qui modifie la couleur de la ligne inférieure d’ EditText de manière plus simple:

 private void updateEditTextBackground() { ensureBackgroundDrawableStateWorkaround(); final Drawable editTextBackground = mEditText.getBackground(); if (editTextBackground == null) { return; } if (mErrorShown && mErrorView != null) { // Set a color filter of the error color editTextBackground.setColorFilter( AppCompatDrawableManager.getPorterDuffColorFilter( mErrorView.getCurrentTextColor(), PorterDuff.Mode.SRC_IN)); } ... } 

Il semble que tout le code ci-dessus devienne inutile maintenant en 23.2.0 si vous voulez changer la couleur par programme.

Et si vous voulez supporter toutes les plateformes, voici ma méthode:

 /** * Set backgroundTint to {@link View} across all targeting platform level. * @param view the {@link View} to tint. * @param color color used to tint. */ public static void tintView(View view, int color) { final Drawable d = view.getBackground(); final Drawable nd = d.getConstantState().newDrawable(); nd.setColorFilter(AppCompatDrawableManager.getPorterDuffColorFilter( color, PorterDuff.Mode.SRC_IN)); view.setBackground(nd); } 

Moi aussi j’ai été bloqué sur ce problème trop longtemps.

J’avais besoin d’une solution qui fonctionnait pour les versions supérieures et inférieures à la v21.

J’ai finalement découvert une solution très simple, peut-être pas idéale mais efficace: Il suffit de définir la couleur d’arrière-plan sur transparent dans les propriétés EditText.

  

J’espère que cela fera gagner du temps à quelqu’un.

Pour moi, j’ai modifié à la fois AppTheme et une valeur colors.xml colorControlNormal et colorAccent m’ont aidé à changer la couleur de la bordure EditText. Ainsi que le curseur et le “|” à l’intérieur d’un EditText.

  

Voici les colors.xml

   #B7EC2A  

J’ai sorti l’atsortingbut android: textCursorDrawable à @null que j’ai placé dans le style editText. Quand j’ai essayé d’utiliser ceci, les couleurs ne changeraient pas.

Vous pouvez définir un arrière-plan de edittext sur un rectangle avec un remplissage moins à gauche, à droite et en haut pour y parvenir. Voici l’exemple xml:

        

Remplacez la forme par un sélecteur si vous souhaitez fournir une largeur et une couleur différentes pour un edittext ciblé.

J’utilise cette méthode pour changer la couleur de la ligne avec PorterDuff, sans autre dessin.

 public void changeBottomColorSearchView(int color) { int searchPlateId = mSearchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null); View searchPlate = mSearchView.findViewById(searchPlateId); searchPlate.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN); } 

Il est très facile d’append simplement l’atsortingbut android:backgroundTint dans votre EditText .

 android:backgroundTint="@color/blue" android:backgroundTint="#ffffff" android:backgroundTint="@color/red"  

Si vous souhaitez modifier la ligne du bas sans utiliser les couleurs de l’application, utilisez ces lignes dans votre thème:

 @android:style/Widget.EditText @android:style/Widget.EditText 

Je ne connais pas d’autre solution.

Dans Activit.XML ajoutez le code

  

BackgroundTint=color pour la couleur désirée

J’ai mis au point une solution de travail après 2 jours de lutte, la solution ci-dessous est parfaite pour ceux qui veulent changer peu de texte d’édition, changer / basculer la couleur à travers le code java et surmonter les problèmes de comportement sur les versions OS. en raison d’utiliser la méthode setColorFilter ()

  import android.content.Context; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.AppCompatDrawableManager; import android.support.v7.widget.AppCompatEditText; import android.util.AtsortingbuteSet; import com.newco.cooltv.R; public class RqubeErrorEditText extends AppCompatEditText { private int errorUnderlineColor; private boolean isErrorStateEnabled; private boolean mHasReconstructedEditTextBackground; public RqubeErrorEditText(Context context) { super(context); initColors(); } public RqubeErrorEditText(Context context, AtsortingbuteSet attrs) { super(context, attrs); initColors(); } public RqubeErrorEditText(Context context, AtsortingbuteSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initColors(); } private void initColors() { errorUnderlineColor = R.color.et_error_color_rule; } public void setErrorColor() { ensureBackgroundDrawableStateWorkaround(); getBackground().setColorFilter(AppCompatDrawableManager.getPorterDuffColorFilter( ContextCompat.getColor(getContext(), errorUnderlineColor), PorterDuff.Mode.SRC_IN)); } private void ensureBackgroundDrawableStateWorkaround() { final Drawable bg = getBackground(); if (bg == null) { return; } if (!mHasReconstructedEditTextBackground) { // This is gross. There is an issue in the platform which affects container Drawables // where the first drawable resortingeved from resources will propogate any changes // (like color filter) to all instances from the cache. We'll try to workaround it... final Drawable newBg = bg.getConstantState().newDrawable(); //if (bg instanceof DrawableContainer) { // // If we have a Drawable container, we can try and set it's constant state via // // reflection from the new Drawable // mHasReconstructedEditTextBackground = // DrawableUtils.setContainerConstantState( // (DrawableContainer) bg, newBg.getConstantState()); //} if (!mHasReconstructedEditTextBackground) { // If we reach here then we just need to set a brand new instance of the Drawable // as the background. This has the unfortunate side-effect of wiping out any // user set padding, but I'd hope that use of custom padding on an EditText // is limited. setBackgroundDrawable(newBg); mHasReconstructedEditTextBackground = true; } } } public boolean isErrorStateEnabled() { return isErrorStateEnabled; } public void setErrorState(boolean isErrorStateEnabled) { this.isErrorStateEnabled = isErrorStateEnabled; if (isErrorStateEnabled) { setErrorColor(); invalidate(); } else { getBackground().mutate().clearColorFilter(); invalidate(); } } } 

Utilise en xml

  

Ajouter des lignes avec style

  

code java pour basculer la couleur

 myRqubeEditText.setErrorState(true); myRqubeEditText.setErrorState(false); 

J’ai été absolument déconcerté par ce problème. J’avais tout essayé dans ce fil, et dans d’autres, mais peu importe ce que je faisais, je ne pouvais pas changer la couleur du soulignement autrement que le bleu par défaut.

J’ai finalement compris ce qui se passait. J’utilisais (à tort) android.widget.EditText lors de la création d’une nouvelle instance (mais le rest de mes composants provenait de la bibliothèque appcompat). J’aurais dû utiliser android.support.v7.widget.AppCompatEditText . J’ai remplacé le new EditText(this) par un new AppCompatEditText(this) et le problème a été résolu instantanément. Il s’avère que si vous utilisez réellement AppCompatEditText , il respectera simplement l’ accentColor de votre thème (comme mentionné dans plusieurs commentaires ci-dessus) et aucune configuration supplémentaire n’est nécessaire.

C’est le plus simple et le plus efficace / réutilisable / fonctionne sur toutes les API
Créez une classe EditText personnalisée comme suit:

 public class EditText extends android.widget.EditText { public EditText(Context context) { super(context); init(); } public EditText(Context context, AtsortingbuteSet attrs) { super(context, attrs); init(); } public EditText(Context context, AtsortingbuteSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { getBackground().mutate().setColorFilter(ContextCompat.getColor(getContext(), R.color.colorAccent), PorterDuff.Mode.SRC_ATOP); } } 

Ensuite, utilisez-le comme ceci:

   

Pour modifier dynamicment l’arrière-plan EditText, vous pouvez utiliser ColorStateList .

 int[][] states = new int[][] { new int[] { android.R.attr.state_enabled}, // enabled new int[] {-android.R.attr.state_enabled}, // disabled new int[] {-android.R.attr.state_checked}, // unchecked new int[] { android.R.attr.state_pressed} // pressed }; int[] colors = new int[] { Color.BLACK, Color.RED, Color.GREEN, Color.BLUE }; ColorStateList colorStateList = new ColorStateList(states, colors); 

Crédits: Cette réponse SO à propos de ColorStateList est géniale .

Veuillez modifier cette méthode en fonction de vos besoins. Cela a fonctionné pour moi!

  private boolean validateMobilenumber() { if (mobilenumber.getText().toSsortingng().sortingm().isEmpty() || mobilenumber.getText().toSsortingng().length() < 10) { input_layout_mobilenumber.setErrorEnabled(true); input_layout_mobilenumber.setError(getString(R.string.err_msg_mobilenumber)); // requestFocus(mobilenumber); return false; } else { input_layout_mobilenumber.setError(null); input_layout_mobilenumber.setErrorEnabled(false); mobilenumber.setBackground(mobilenumber.getBackground().getConstantState().newDrawable()); }