Изменение цвета нижней строки EditText с помощью appcompat v7
я использую appcompat v7, чтобы получить согласованный внешний вид на Android 5 и меньше. Это работает довольно хорошо. Однако я не могу понять, как изменить цвет нижней строки и цвет акцента Для редактирования текстов. Возможно ли это?
Я попытался определить пользовательскую android:editTextStyle (МФ. ниже), но мне удалось изменить только полный цвет фона или цвет текста, но не нижнюю строку и цвет акцента. Есть ли конкретное значение свойства для использования? должен ли я использовать пользовательское рисованное изображение через android:background собственность? это не возможно, чтобы указать цвет в Гекса?
<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>
согласно источникам Android API 21, EditTexts с материальным дизайном, похоже, используют colorControlActivated и colorControlNormal. Поэтому я попытался переопределить эти свойства в предыдущем определении стиля, но это не имеет никакого эффекта. Вероятно, appcompat не использует его. К сожалению, я не могу найти источники для последней версии appcompat с material design.
23 ответов:
наконец, я нашел решение. Он просто состоит из переопределения значения для
colorControlActivated,colorControlHighlightиcolorControlNormalв определении темы приложения, а не в вашем стиле edittext. Затем подумайте, чтобы использовать эту тему для любой деятельности вы хотите. Ниже приведен пример:<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>
Я чувствовал, что это нужен ответ в случае, если кто-то хочет изменить только один edittext. Я делаю это так:
editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);
пока Laurents solution правильно, он поставляется с некоторыми недостатками, как описано в комментариях, так как не только нижняя строка
EditTextполучает тонировку, но кнопка НазадToolbar,CheckBoxesetc. также.к счастью
v22.1наappcompat-v7ввел некоторые новые возможности. Теперь можно назначить определенную тему только для одного представления. Прямо из список изменений:устаревшее использование приложения: тема для панель инструментов укладки. теперь вы можете использовать android: тема для панелей инструментов на всех устройствах уровня API 7 и выше и android: тема поддержка для всех виджетов на устройствах уровня API 11 и выше.
поэтому вместо того, чтобы устанавливать нужный цвет в глобальной теме, мы создаем новый и назначаем его только
EditText.пример:
<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"/>
вот решение для API и выше
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 }надеюсь, что это поможет
принятый ответ немного больше за основу стиля, но самое эффективное, что нужно сделать, это добавить colorAccent атрибут в вашем стиле AppTheme, как это:
<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"/>атрибут colorAccent используется для тонировки виджетов по всему приложению и, следовательно, должен использоваться для согласованности
Если вы используете
appcompat-v7:22.1.0+можно использовать DrawableCompat чтобы подкрасить виджетыpublic static void tintWidget(View view, int color) { Drawable wrappedDrawable = DrawableCompat.wrap(view.getBackground()); DrawableCompat.setTint(wrappedDrawable.mutate(), getResources().getColor(color)); view.setBackgroundDrawable(wrappedDrawable); }
использование:
<EditText app:backgroundTint="@color/blue"/>Это будет поддерживать pre-Lollipop устройства не только +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>
одним из быстрых решений для вашей проблемы является поиск в yourappspackage / build / intermediates/exploded-aar / com.андроид.поддержка / appcompat-v7/res/ drawable / для abc_edit_text_material.xml и скопируйте этот xml-файл в свою папку для рисования. Затем вы можете изменить цвет 9 файлов патчей изнутри этого селектора, чтобы соответствовать вашим предпочтениям.
вот часть исходного кода
TextInputLayoutв библиотеке дизайна поддержки (обновлено для версии 23.2.0), которая изменяетEditTextнижняя линия цвет в более простой способ: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)); } ... }кажется, что все вышеперечисленные коды становятся бесполезными прямо сейчас в 23.2.0, если вы хотите изменить цвет программно.
и если вы хотите поддерживать все платформы, вот мой способ:
/** * 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); }
Я тоже застрял на этой проблеме слишком долго.
мне требовалось решение, которое работало для версий выше и ниже v21.
Я, наконец, обнаружил очень простое, возможно, не идеальное, но эффективное решение: просто установите цвет фона в
transparentв свойствах EditText.<EditText android:background="@android:color/transparent"/>Я надеюсь, это сэкономит кому-то немного времени.
для меня я изменил как AppTheme и значение цвета.xml как colorControlNormal, так и colorAccent помогли мне изменить цвет границы EditText. А также курсор, и"|", когда внутри 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>здесь цвета.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="yellow">#B7EC2A</color> </resources>Я достал атрибут android: textCursorDrawable для @null, который я разместил внутри стиля editText. Когда я попытался использовать это, цвета не изменятся.
Это очень легко просто добавить
android:backgroundTintатрибут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"/>
вы можете установить фон edittext в прямоугольник с минусовым заполнением слева, справа и сверху, чтобы достичь этого. Вот пример 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>замените фигуру селектором, если вы хотите предоставить другую ширину и цвет для сфокусированного edittext.
Я использую этот метод, чтобы изменить цвет линии с PorterDuff, без каких-либо других drawable.
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); }
Если вы хотите изменить нижнюю строку без использования цветов приложения, используйте эти строки в своей теме:
<item name="android:editTextStyle">@android:style/Widget.EditText</item> <item name="editTextStyle">@android:style/Widget.EditText</item>Я не знаю другого решения.
В Activit.XML добавить код
<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для вашего желаемого цвет
Я разработал рабочее решение этой проблемы после 2 дней борьбы, ниже решение идеально подходит для тех, кто хочет изменить несколько редактировать текст только, изменить/переключить цвет через java-код, и хотите преодолеть проблемы различного поведения на версиях ОС из-за использования метода 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(); } } }использует в 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"/>добавить строки в стиле
<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>java-код для переключения цвета
myRqubeEditText.setErrorState(true); myRqubeEditText.setErrorState(false);
Я был абсолютно озадачен этой проблемой. Я пробовал все в этой теме и в других, но независимо от того, что я сделал, я не мог изменить цвет подчеркивания ни на что другое, кроме синего цвета по умолчанию.
я, наконец, понял, что происходит. Я был (неправильно) с помощью
android.widget.EditTextпри создании нового экземпляра (но остальные мои компоненты были из библиотеки appcompat). Я должен был использоватьandroid.support.v7.widget.AppCompatEditText. Я заменилnew EditText(this)Сnew AppCompatEditText(this)и проблема была мгновенно разрешенный. Оказывается, если вы на самом деле используетеAppCompatEditText, он будет просто уважатьaccentColorиз вашей темы (Как упоминалось в нескольких комментариях выше) и никакой дополнительной конфигурации не требуется.
Это самый простой и эффективный/многоразовый/работает на всех API
Создайте пользовательский класс EditText следующим образом: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); } }тогда используйте его так:
<company.com.app.EditText android:layout_width="200dp" android:layout_height="wrap_content"/>
для динамического изменения фона EditText можно использовать 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);благодарности: это так ответ о ColorStateList является удивительным.
пожалуйста, измените этот метод в соответствии с вашими потребностями. Это сработало для меня!
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()); }

Comments