使用appcompat v7更改EditText底线颜色

我正在使用appcompat v7在Android 5或更less版本上获得一致的外观。 它工作得很好。 但是我不知道如何改变EditTexts的底线颜色和重音颜色。 可能吗?

我试图定义一个自定义的android:editTextStyle (参见下面),但我只能成功地更改完整的背景颜色或文本颜色,但不是底线,也没有重音颜色。 有没有一个特定的属性值使用? 我必须通过android:background属性使用自定义的可绘制图像吗? 是不是可以在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> 

根据android API 21来源,具有材质devise的EditTexts似乎使用了colorControlActivatedcolorControlNormal 。 因此,我试图在先前的样式定义中覆盖这些属性,但是它没有效果。 可能appcompat不使用它。 不幸的是,我无法find材质devise的最后一个版本的appcompat的来源。

最后,我find了一个解决scheme。 它只是在应用程序主题定义中覆盖colorControlActivatedcolorControlHighlightcolorControlNormal的值,而不是您的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.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP); 

虽然Laurents解决scheme是正确的,但它带有一些缺点,如评论中所述,因为不仅EditText的底线被着色,还有ToolbarCheckBoxes等的Back Button。

幸运的是, appcompat-v7appcompat-v7引入了一些新的可能性。 现在可以将一个特定的主题只分配给一个视图。 直接从变更日志 :

不推荐使用app:theme来创build样式工具栏。 现在,您可以在所有API级别为7及更高的设备上使用 android:主题工具栏,并在API级别为11及更高的设备上使用所有窗口小部件的 android:theme支持。

因此,我们不是在全局主题中设置所需的颜色,而是创build一个新的,并将其仅分配给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"/> 

以供参考。 这可以通过使用以下命令在xml中进行更改:

 android:backgroundTint="@color/blue" 

这是API <21及以上的解决scheme

 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"/> 

这将不仅支持+21前棒棒糖设备

你的问题的一个快速解决scheme是在你的drawable文件夹中查找yourappspackage / build / intermediates / exploded-aar / com.android.support / appcompat-v7 / res / drawable / for abc_edit_text_material.xml。 然后,您可以从该select器内改变9个补丁文件的颜色,以符合您的偏好。

 <!-- 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> 

下面是支持devise库( 更新版本23.2.0 )中的TextInputLayout源代码的一部分,它以更简单的方式改变了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以上和以下版本的解决scheme。

我终于发现了一个非常简单的可能并不理想但有效的解决scheme:只需在EditText属性中将背景颜色设置为transparent即可。

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

我希望这能节省一些时间。

对我来说,我修改了AppTheme和一个值colors.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> 

这是colors.xml

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

我拿出了android:textCursorDrawable属性@null,我把它放在editText样式中。 当我尝试使用这个,颜色不会改变。

如果您想要改变底线而不使用应用颜色,请在您的主题中使用以下几行:

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

我不知道另一个解决scheme。

您可以将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提供不同的宽度和颜色,请用select器replace形状。

在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所需颜色的颜色

我用这个方法来改变PorterDuff的行颜色,没有其他可绘制的。

 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); } 

经过2天的努力,我find了解决这个问题的办法,下面的解决scheme对于那些只想改变一些编辑文本,通过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 AppCompatEditText(this)replace了new EditText(this) ,问题立即解决了。 事实certificate,如果你实际使用的是AppCompatEditText ,那么它只会尊重主题中的accentColor (如上面几个注释中所提到的),不需要额外的configuration。

这是所有API上最简单和最有效/可重用/可用的
像这样创build一个自定义的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中添加android:backgroundTint属性即可。

 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"/> 

要dynamic更改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()); }