Changer la couleur de la ligne de fond D'EditText avec appcompat v7

j'utilise appcompat v7 pour obtenir le look cohérent sur Android 5 et moins. Il fonctionne plutôt bien. Cependant je ne peux pas comprendre comment changer la couleur de la ligne de fond et la couleur de l'accent pour les textes. Est-il possible?

j'ai essayé de définir une coutume android:editTextStyle (cf. ci-dessous) mais j'ai seulement réussi à changer la couleur de fond complète ou la couleur du texte, mais pas la ligne de fond ni la couleur de l'accent. Est-t-il une valeur de propriété à utiliser? est-ce que je dois utiliser une coutume une image dessinable à travers la propriété android:background ? il n'est pas possible de spécifier une couleur en hexa?

 <style name="Theme.App.Base" parent="Theme.AppCompat.Light.DarkActionBar">
     <item name="android:editTextStyle">@style/Widget.App.EditText</item>
 </style>

 <style name="Widget.App.EditText" parent="Widget.AppCompat.EditText">
     ???
 </style>

selon les sources de l'API 21 d'android, EditTexts with material design semble utiliser colorControlActivated et colorControlNormal . Par conséquent, j'ai essayé d'outrepasser ces propriétés dans la définition de style précédente, mais cela n'a aucun effet. Probablement appcompat ne l'utilise pas. Malheureusement, je ne trouve pas les sources pour la dernière version d'appcompat avec la conception du matériel.

280
demandé sur l-l 2014-10-26 17:56:37

23 réponses

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

<style name="Theme.App.Base" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorControlNormal">#c5c5c5</item>
    <item name="colorControlActivated">@color/accent</item>
    <item name="colorControlHighlight">@color/accent</item>
</style>
463
répondu Laurent 2015-06-20 08:02:42

j'ai senti que cela avait besoin d'une réponse au cas où quelqu'un voulait changer juste un simple texte d'édition. Je le fais comme ceci:

editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);
180
répondu hordurh 2016-02-05 10:41:17

alors que Laurents solution est correct, il vient avec quelques inconvénients comme décrit dans les commentaires puisque non seulement la ligne de fond du EditText est teinté, mais le bouton arrière du Toolbar , CheckBoxes , etc. ainsi.

heureusement v22.1 de appcompat-v7 introduit de nouvelles possibilités. Il est maintenant possible d'attribuer un thème spécifique à une seule vue. Directement du Changelog :

utilisation dépréciée 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 API Niveau 7 et supérieur et android:Thème prise en charge pour tous les widgets sur les appareils API Niveau 11 et supérieur.

donc au lieu de définir la couleur désirée dans un thème global, nous en créons un nouveau et l'assignons seulement au EditText .

exemple:

<style name="MyEditTextTheme">
    <!-- Used for the bottom line when not selected / focused -->
    <item name="colorControlNormal">#9e9e9e</item>
    <!-- colorControlActivated & colorControlHighlight use the colorAccent color by default -->
</style>

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/MyEditTextTheme"/>
137
répondu reVerse 2017-05-23 12:26:43

Pour Référence. Ceci peut être modifié en xml en utilisant:

android:backgroundTint="@color/blue"
90
répondu l-l 2015-04-01 20:59:05

Voici la solution pour API < 21 et plus

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
}

enter image description here

Espoir aide

45
répondu Phan Van Linh 2017-02-23 01:48:16

la réponse acceptée est un peu plus Par style base chose, mais la chose la plus efficace à faire est d'ajouter le colorAccent attribut dans votre style AppTheme comme ceci:

<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:editTextStyle">@style/EditTextStyle</item>
</style>

<style name="EditTextStyle" parent="Widget.AppCompat.EditText"/>

l'attribut colorAccent est utilisé pour la teinture des widgets dans toute l'application et doit donc être utilisé pour la cohérence

34
répondu TanmayP 2014-11-05 22:30:07

si vous utilisez appcompat-v7:22.1.0+ vous pouvez utiliser le DrawableCompat pour tordre 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);
    }
28
répondu Felipe Conde 2016-04-04 09:24:59

utiliser:

<EditText
    app:backgroundTint="@color/blue"/>

cela permettra de prendre en charge les dispositifs pré-Lollipop non seulement +21

18
répondu blueware 2016-09-27 12:24:02

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="colorControlNormal">@color/colorAccent</item>
    <item name="colorControlActivated">@color/colorAccent</item>
    <item name="colorControlHighlight">@color/colorAccent</item>

</style>

16
répondu Ashwin H 2017-01-20 08:50:31

Une solution rapide à votre problème est de regarder dans yourappspackage/build/intermédiaires/a explosé-aar/com.Android.support / appcompat-v7/res/ drawable / for abc_edit_text_material.xml et copier ce fichier xml dans votre dossier drawable. Vous pouvez ensuite modifier la couleur des 9 fichiers de patch à partir de ce sélecteur, afin de correspondre à vos préférences.

12
répondu Peter 2014-10-28 08:46:58

Voici une partie du code source de TextInputLayout dans la bibliothèque de conception de soutien ( mis à jour pour la version 23.2.0 ), qui change la couleur de la ligne de fond de EditText d'une 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 tous les codes ci-dessus deviennent inutiles en ce moment dans 23.2.0 si vous voulez changer la couleur programatiquement.

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);
}
7
répondu ywwynm 2016-03-01 11:10:19

moi aussi j'ai été coincé sur ce problème pendant trop longtemps.

j'ai eu besoin d'une solution qui a fonctionné pour les versions au-dessus et en dessous de v21.

j'ai finalement découvert une solution très simple peut-être pas idéale mais efficace: il suffit de régler la couleur de fond à transparent dans les propriétés EditText.

<EditText
    android:background="@android:color/transparent"/>

j'espère que ça fera gagner du temps à quelqu'un.

7
répondu Mtl Dev 2016-05-28 15:29:33

pour moi j'ai modifié à la fois L'Appthème et une valeur couleurs.xml à la fois le colorControlNormal et le colorAccent m'ont aidé à changer la couleur de la bordure EditText. Ainsi que le curseur, et le "|" lorsque dans un texte édité.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorControlNormal">@color/yellow</item>
    <item name="colorAccent">@color/yellow</item>
</style>

Voici les couleurs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="yellow">#B7EC2A</color>
</resources>

j'ai sorti l'attribut android:textCursorDrawable De @null que j'ai placé dans le style editText. Quand j'ai essayé de l'utiliser, les couleurs ne changeaient pas.

6
répondu Emily Alexandra Conroyd 2016-02-22 16:59:08

il est très facile d'ajouter android:backgroundTint dans votre attribut EditText .

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


 <EditText
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:backgroundTint="#ffffff"/>
6
répondu Pacific P. Regmi 2018-04-06 11:19:45

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);
}
5
répondu user2721167 2016-10-25 14:17:59

si vous voulez changer la ligne de fond sans utiliser les couleurs de l'application, Utilisez ces lignes dans votre thème:

<item name="android:editTextStyle">@android:style/Widget.EditText</item>
<item name="editTextStyle">@android:style/Widget.EditText</item>

Je ne connais pas d'autre solution.

4
répondu rz0 2015-05-05 09:04:58

In Activit.Ajouter le code

<EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:id="@+id/editText"
        android:hint="Informe o usuário"
        android:backgroundTint="@android:color/transparent"/>

BackgroundTint=color pour la couleur désirée

4
répondu M.Zanella 2016-10-14 00:19:00

j'ai élaboré une solution de travail à ce problème après 2 jours de lutte, la solution ci-dessous est parfaite pour ceux qui veulent changer peu éditer le texte seulement, changer/changer la couleur par le code java, et veulent surmonter les problèmes de comportement différent sur les versions D'OS en raison de l'utilisation de 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.AttributeSet;
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, AttributeSet attrs) {
    super(context, attrs);
    initColors();
  }

  public RqubeErrorEditText(Context context, AttributeSet 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 retrieved 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

<com.rqube.ui.widget.RqubeErrorEditText
            android:id="@+id/f_signup_et_referral_code"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/referral_iv"
            android:layout_toRightOf="@+id/referral_iv"
            android:ems="10"
            android:hint="@string/lbl_referral_code"
            android:imeOptions="actionNext"
            android:inputType="textEmailAddress"
            android:textSize="@dimen/text_size_sp_16"
            android:theme="@style/EditTextStyle"/>

ajouter des lignes dans le style

<style name="EditTextStyle" parent="android:Widget.EditText">
    <item name="android:textColor">@color/txt_color_change</item>
    <item name="android:textColorHint">@color/et_default_color_text</item>
    <item name="colorControlNormal">@color/et_default_color_rule</item>
    <item name="colorControlActivated">@color/et_engagged_color_rule</item>
  </style>

code java pour changer la couleur

myRqubeEditText.setErrorState(true);
myRqubeEditText.setErrorState(false);
3
répondu RQube 2016-06-29 12:49:01

j'étais absolument déconcerté par ce problème. J'avais tout essayé dans ce fil, et dans d'autres, mais peu importe ce que j'ai fait je ne pouvais pas changer la couleur du soulignement à rien d'autre que le bleu par défaut.

j'ai enfin compris ce qui se passait. J'utilisais (incorrectement) android.widget.EditText pour créer une nouvelle instance (mais le reste de mes composants provenait de la bibliothèque appcompat). J'aurais dû utiliser android.support.v7.widget.AppCompatEditText . J'ai remplacé new EditText(this) par new AppCompatEditText(this) et le problème fut instantanément résolu. Il s'avère que, si vous utilisez réellement AppCompatEditText , il ne respectera que le accentColor de votre thème (comme mentionné dans plusieurs commentaires ci-dessus) et aucune configuration supplémentaire n'est nécessaire.

2
répondu mkasberg 2016-02-15 04:05:41

C'est le plus facile et le plus efficace / réutilisable / fonctionne sur tous les APIs

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, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public EditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        getBackground().mutate().setColorFilter(ContextCompat.getColor(getContext(), R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
    }
}

alors utilisez - le comme ceci:

 <company.com.app.EditText
        android:layout_width="200dp"
        android:layout_height="wrap_content"/>
2
répondu Oliver Dixon 2016-03-24 15:03:49

pour changer dynamiquement le fond 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 AFIN de répondre à propos de ColorStateList est génial .

1
répondu Ankit Popli 2017-05-23 11:33:25

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

  private boolean validateMobilenumber() {
        if (mobilenumber.getText().toString().trim().isEmpty() || mobilenumber.getText().toString().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());
        }
-2
répondu Shahid Sarwar 2016-10-25 13:41:22