java - studio - edittext line color
Cambio del color de la lĂnea de fondo de EditText con appcompat v7 (23)
Estoy usando appcompat v7 para obtener un aspecto consistente en Android 5 y menos. Funciona bastante bien Sin embargo, no puedo entender cómo cambiar el color de la línea de fondo y el color de acento para EditTexts. ¿Es posible?
Intenté definir un
android:editTextStyle
personalizado
android:editTextStyle
(ver abajo) pero solo logré cambiar el color de fondo completo o el color del texto, pero no la línea de fondo ni el color de énfasis.
¿Hay un valor de propiedad específico para usar?
¿Tengo que usar una imagen dibujable personalizada a través de la propiedad
android:background
?
¿No es posible especificar un color 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>
Según las fuentes de Android API 21, EditTexts con diseño de material parece usar
colorControlActivated
y
colorControlNormal
.
Por lo tanto, he intentado anular estas propiedades en la definición de estilo anterior, pero no tiene ningún efecto.
Probablemente appcompat no lo use.
Desafortunadamente, no puedo encontrar las fuentes para la última versión de appcompat con diseño de material.
Aquí está la solución para API <21 y superior
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
}
Espero que ayude
Aquí hay una parte del código fuente de
TextInputLayout
en la biblioteca de diseño de soporte (
ACTUALIZADO para la versión 23.2.0
), que cambia el color de la línea de fondo de
EditText
una manera más 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));
}
...
}
Parece que todo el código anterior se vuelve inútil en este momento en 23.2.0 si desea cambiar el color mediante programación.
Y si quieres soportar todas las plataformas, aquí está mi método:
/**
* 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);
}
Desarrollé una solución funcional para este problema después de 2 días de lucha, la solución a continuación es perfecta para aquellos que desean cambiar solo algunos textos de edición, cambiar / alternar el color a través del código de Java y quieren superar los problemas de comportamiento diferente en las versiones del sistema operativo debido al uso del método 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();
}
}
}
Usos 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"/>
Agregar líneas con estilo
<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>
código de Java para alternar color
myRqubeEditText.setErrorState(true);
myRqubeEditText.setErrorState(false);
En Activit.XML agregue el código
<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"/>
Donde
BackgroundTint=color
para el color deseado
Es muy fácil simplemente agregue el atributo
android:backgroundTint
en su
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"/>
Estaba absolutamente desconcertado por este problema. Había intentado todo en este hilo y en otros, pero sin importar lo que hice, no pude cambiar el color del subrayado a otro que no sea el azul predeterminado.
Finalmente descubrí lo que estaba pasando.
Estaba (incorrectamente) usando
android.widget.EditText
al hacer una nueva instancia (pero el resto de mis componentes eran de la biblioteca appcompat).
Debería haber usado
android.support.v7.widget.AppCompatEditText
.
new EditText(this)
con el
new AppCompatEditText(this)
y el problema se resolvió instantáneamente.
Resulta que si realmente está usando
AppCompatEditText
, solo respetará el
accentColor
de su tema (como se menciona en varios comentarios anteriores) y no es necesaria una configuración adicional.
Este es el más fácil y más eficiente / reutilizable / funciona en todas las API
Cree una clase personalizada de EditText así:
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);
}
}
Entonces úsalo así:
<company.com.app.EditText
android:layout_width="200dp"
android:layout_height="wrap_content"/>
Finalmente, he encontrado una solución.
Simplemente consiste en anular el valor de
colorControlActivated
,
colorControlHighlight
y
colorControlNormal
en la definición del tema de la aplicación y no en el estilo de edición de texto.
Luego, piense en usar este tema para cualquier actividad que desee.
A continuación se muestra un ejemplo:
<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>
La respuesta aceptada es un poco más por estilo, pero lo más eficiente es agregar el atributo colorAccent en su estilo AppTheme de esta manera:
<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"/>
El atributo colorAccent se usa para teñir los widgets en toda la aplicación y, por lo tanto, debe usarse para mantener la coherencia
Modifique este método según sus necesidades. ¡Esto funcionó para mí!
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());
}
Para cambiar el fondo EditText dinámicamente, puede usar 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éditos: Esta respuesta SO sobre ColorStateList es increíble .
Para mí modifiqué tanto el AppTheme como un valor colors.xml Tanto el colorControlNormal como el colorAccent me ayudaron a cambiar el color del borde EditText. Así como el cursor y el "|" cuando dentro de un EditText.
<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>
Aquí está el colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="yellow">#B7EC2A</color>
</resources>
Saqué el atributo android: textCursorDrawable a @null que coloqué dentro del estilo editText. Cuando intenté usar esto, los colores no cambiaron.
Para referencia. Esto se puede cambiar en xml usando:
android:backgroundTint="@color/blue"
Para compatibilidad con versiones anteriores, use:
app:backgroundTint="@color/blue"
Puede configurar el fondo del texto de edición en un rectángulo con relleno menos a la izquierda, derecha y arriba para lograr esto. Aquí está el ejemplo xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:top="-1dp"
android:left="-1dp"
android:right="-1dp"
android:bottom="1dp"
>
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#6A9A3A"/>
</shape>
</item>
</layer-list>
Reemplace la forma con un selector si desea proporcionar un ancho y un color diferentes para el texto de edición enfocado.
Sentí que esto necesitaba una respuesta en caso de que alguien quisiera cambiar solo un texto de edición. Lo hago así:
editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);
Si bien la
solución de Laurents
es correcta, viene con algunos inconvenientes como se describe en los comentarios, ya que no solo la línea inferior del
EditText
se
EditText
sino también el Botón Atrás de la
Toolbar
de
Toolbar
,
EditText
de
EditText
, etc.
Afortunadamente,
v22.1
de
appcompat-v7
introdujo algunas nuevas posibilidades.
Ahora es posible asignar un tema específico solo a una vista.
Directamente desde el
Changelog
:
Uso obsoleto de la aplicación: tema para el diseño de la barra de herramientas. Ahora puede usar android: theme para barras de herramientas en todos los dispositivos API nivel 7 y superior y android: tema de soporte para todos los widgets en dispositivos API nivel 11 y superior.
Entonces, en lugar de establecer el color deseado en un tema global, creamos uno nuevo y lo asignamos solo al
EditText
.
Ejemplo:
<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"/>
Si desea cambiar el resultado final sin usar los colores de la aplicación, use estas líneas en su tema:
<item name="android:editTextStyle">@android:style/Widget.EditText</item>
<item name="editTextStyle">@android:style/Widget.EditText</item>
No conozco otra solución.
Si está usando
appcompat-v7:22.1.0+
, puede usar
DrawableCompat
para teñir sus 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);
}
Una solución rápida para su problema es buscar en su paquete / build / intermedios / exploded-aar / com.android.support / appcompat-v7 / res / drawable / for abc_edit_text_material.xml y copiar ese archivo xml en su carpeta dibujable. Luego puede cambiar el color de los 9 archivos de parche desde este selector, para que coincida con sus preferencias.
Utilizar:
<EditText
app:backgroundTint="@color/blue"/>
Esto admitirá dispositivos pre-Lollipop no solo +21
Utilizo este método para cambiar el color de la línea con PorterDuff, sin ningún otro dibujo.
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);
}
Yo también estuve atrapado en este problema durante demasiado tiempo.
Necesitaba una solución que funcionara para las versiones anteriores y posteriores a v21.
Finalmente descubrí una solución muy simple, quizás no ideal pero efectiva: simplemente configure el color de fondo como
transparent
en las propiedades de EditText.
<EditText
android:background="@android:color/transparent"/>
Espero que esto ahorre algo de tiempo.
<!-- 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>