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.
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>
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);
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"/>
Pour Référence. Ceci peut être modifié en xml en utilisant:
android:backgroundTint="@color/blue"
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
}
Espoir aide
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
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);
}
utiliser:
<EditText
app:backgroundTint="@color/blue"/>
cela permettra de prendre en charge les dispositifs pré-Lollipop non seulement +21
<!-- 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>
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.
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);
}
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.
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.
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"/>
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);
}
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.
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"/>
où BackgroundTint=color
pour la couleur désirée
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);
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.
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"/>
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 .
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());
}