使用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似乎使用了colorControlActivated
和colorControlNormal
。 因此,我试图在先前的样式定义中覆盖这些属性,但是它没有效果。 可能appcompat不使用它。 不幸的是,我无法find材质devise的最后一个版本的appcompat的来源。
最后,我find了一个解决scheme。 它只是在应用程序主题定义中覆盖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.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);
虽然Laurents解决scheme是正确的,但它带有一些缺点,如评论中所述,因为不仅EditText
的底线被着色,还有Toolbar
, CheckBoxes
等的Back Button。
幸运的是, appcompat-v7
的appcompat-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()); }