使用appcompat v7更改EditText底线颜色

我使用appcompat v7,以获得在Android 5和更少的外观一致。它运行得相当好。但是,我不知道如何更改EditTexts的底线颜色和强调色。这可能吗?

我试图定义一个自定义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与材料设计似乎使用colorControlActivatedcolorControlNormal。因此,我尝试在前面的样式定义中覆盖这些属性,但没有效果。可能appcompat不使用它。不幸的是,我找不到最新版本的appcompat材料设计的来源。

326814 次浏览

一个快速的解决方法是查看你的appspackage/build/intermediates/ explo- aar/com.android。支持/appcompat-v7/res/drawable/ abc_edit_text_material.xml并将该XML文件复制到drawable文件夹中。然后你可以在这个选择器中改变9个补丁文件的颜色,以匹配你的偏好。

最后,我找到了一个解决方案。它只是在你的应用主题定义中覆盖colorControlActivatedcolorControlHighlightcolorControlNormal的值,而不是在你的编辑文本样式中。然后,考虑将这个主题用于你想要的任何活动。下面是一个例子:

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

公认的答案是更基于每个样式的东西,但最有效的做法是在你的AppTheme样式中添加colorAccent属性,像这样:

<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属性用于在整个应用程序中为小部件着色,因此应该用于一致性

我觉得这需要一个答案,以防有人想要改变一个编辑文本。我是这样做的:

editText.getBackground().mutate().setColorFilter(ContextCompat.getColor(context, R.color.your_color), PorterDuff.Mode.SRC_ATOP);

可以在XML中使用以下命令更改:

参考API >= 21兼容性使用:

android:backgroundTint="@color/blue"

对于向后的API <21 .兼容性使用:

app:backgroundTint="@color/blue"

如果你想改变底线而不使用应用程序的颜色,在你的主题中使用这些行:

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

我不知道还有别的办法。

虽然劳伦的解决方案是正确的,但它也有一些缺点,正如评论中所描述的,因为不仅EditText的底线会被着色,而且ToolbarCheckBoxes等的返回按钮也会被着色。

幸运的是,appcompat-v7v22.1引入了一些新的可能性。现在可以将特定的主题仅分配给一个视图。直接来自更新日志:

不赞成使用应用程序:主题样式工具栏。您现在可以使用 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"/>

如果你正在使用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);
}

你可以将编辑文本的背景设置为一个矩形,在左侧、右侧和顶部都有负填充来实现这一点。下面是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>

如果要为聚焦的编辑文本提供不同的宽度和颜色,则使用选择器替换形状。

下面是支持设计库(已更新版本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);
}

这个问题完全把我难住了。我已经在这个线程中尝试了所有的东西,但无论我做什么,我都不能改变下划线的颜色,除了默认的蓝色。

我终于搞清楚是怎么回事了。在创建新实例时,我(不正确地)使用了android.widget.EditText(但我的其余组件来自appcompat库)。我应该使用android.support.v7.widget.AppCompatEditText。我用new AppCompatEditText(this)替换了new EditText(this) 问题很快就解决了。事实证明,如果你实际使用AppCompatEditText,它只会尊重你的主题中的accentColor(如上面的几个注释中提到的),不需要额外的配置

对我来说,我修改了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样式。当我尝试使用这个,颜色不会改变。

我用这个方法改变了线条的颜色与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);
}

我也被这个问题困扰了太久。

我需要一个既适用于v21以上版本也适用于v21以下版本的解决方案。

我终于发现了一个非常简单,也许不是理想,但有效的解决方案:简单地设置背景颜色为transparent在EditText属性。

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

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

这是最简单和最有效的/可重用/适用于所有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的答案非常棒

下面是API & lt;21及以上的解决方案

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
}

enter image description here

希望能有所帮助

经过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);

使用:

<EditText
app:backgroundTint="@color/blue"/>

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

在activi . 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为您想要的颜色

请根据您的需要修改此方法。这对我很管用!

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

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

这很简单,只要在你的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"/>

为api级别21以下添加app:backgroundTint。否则使用android:backgroundTint

适用于api级别21以下。

<EditText
android:id="@+id/edt_name"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:textColor="#0012ff"
app:backgroundTint="#0012ff"/>

适用于api等级21以上。

<EditText
android:id="@+id/edt_name"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:textColor="#0012ff"
android:backgroundTint="#0012ff"/>

你可以使用backgroundTint更改编辑文本的底线颜色

 android:backgroundTint="#000000"

例子:

 <EditText
android:id="@+id/title1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#000000" />