使用appcompat v7更改EditText底线颜色

Lau*_*ent 303 java android android-layout android-edittext android-styles

我正在使用appcompat v7来获得Android 5及更低版本的外观.它工作得很好.但是我无法弄清楚如何更改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>
Run Code Online (Sandbox Code Playgroud)

根据android API 21的消息来源,EditTexts与材料设计似乎使用colorControlActivatedcolorControlNormal.因此,我试图在先前的样式定义中覆盖这些属性,但它没有任何效果.可能appcompat不使用它.不幸的是,我找不到上一版appcompat的材料设计来源.

Lau*_*ent 475

最后,我找到了解决方案.它只是由覆盖的价值colorControlActivated,colorControlHighlightcolorControlNormal在您的应用程序主题定义,而不是你的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>
Run Code Online (Sandbox Code Playgroud)

  • 如果您正在使用AppCompat v22支持库,您可以在EditText中指定主题,如:`android:theme ="@ style/Theme.App.Base`.这将确保样式不会影响您的其他视图您不想更改的布局. (68认同)
  • 这会改变底线的颜色,但它也会更改每个其他控件,如复选框,单选按钮等.它还会更改整个Application/Activity中的每个EditText.如果你想改变单个EditText的底线(就像我一样)那么你必须覆盖该EditText的android:background属性.AFAIK别无他法. (10认同)
  • 我看到菜单汉堡包,后退按钮和滚动条的颜色已更改为colorControlNormal. (9认同)
  • 没有在Jelly Bean(4.2)上工作但在Lollipop工作 (8认同)
  • 活动应该继承自`AppCompatActivity`.如果它继承自`Activity`,它将无法工作. (3认同)
  • 我最近遇到了Lollipop前版本的问题.创建自定义EditText会丢失您在AppCompat库中的样式XML中定义的这些颜色.为了保持这些颜色,请看看@hordurh的答案.并在自定义EditText的构造函数中以编程方式使用它. (2认同)

hor*_*urh 185

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

editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);
Run Code Online (Sandbox Code Playgroud)


reV*_*rse 144

虽然Laurents的解决方案是正确的,它带有的,因为不仅是底线在注释中描述的一些缺点EditText被染色,但的后退按钮Toolbar,CheckBoxes等也是如此.

幸运的是v22.1,appcompat-v7介绍了一些新的可能性.现在可以仅将特定主题分配给一个视图.直接来自Changelog:

已弃用app:主题用于样式工具栏.您现在可以在所有API级别7及更高版本的设备上使用 android:theme用于工具栏,并在API级别11及更高版本的设备上使用android:theme支持所有小部件.

因此,我们不是在全局主题中设置所需的颜色,而是创建一个新的颜色并仅将其分配给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>
Run Code Online (Sandbox Code Playgroud)
<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/MyEditTextTheme"/>
Run Code Online (Sandbox Code Playgroud)


l-l*_*l-l 97

以供参考.这可以通过使用以下方式在xml中更改:

android:backgroundTint="@color/blue"
Run Code Online (Sandbox Code Playgroud)

  • 只需使用`backgroundTint ="@ color/blue"`代替`android:backgroundTint ="@ color/blue"`以获得向后兼容的支持 (11认同)
  • 是的,但是这仅适用于Android API版本21+(kitkat和lolipop).人们可能会尝试创建一个向后兼容的解决方案. (10认同)
  • @KishanVaghela,而不是使用`android:backgroundTint ="@ color/blue"`,使用`app:backgroundTint ="@ color/blue"`来支持前Lollipop设备,感谢您的评论! (10认同)
  • @blueware如果你想在风格中使用它,那么我们不需要使用"app". (2认同)

Pha*_*inh 45

这是API <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
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

希望它有所帮助

  • 不再使用支持库24.2.1了 (4认同)

Tan*_*ayP 34

接受的答案是每个样式基础更多一点,但最有效的方法是在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"/>
Run Code Online (Sandbox Code Playgroud)

colorAccent属性用于整个应用程序中的窗口小部件着色,因此应该用于一致性

  • @Tomasz它不需要API 21+,因为父主题是AppCompat,它归结为API 7 (8认同)

Fel*_*nde 28

如果您正在使用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);
    }
Run Code Online (Sandbox Code Playgroud)


blu*_*are 19

使用:

<EditText
    app:backgroundTint="@color/blue"/>
Run Code Online (Sandbox Code Playgroud)

这将支持pre-Lollipop设备不仅+21

  • @ powder366,试试这个:`<style name ="AppTheme"parent ="Theme.AppCompat.Light.NoActionBar">`它应该有效 (2认同)

Ash*_*n H 18

<!-- 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>
Run Code Online (Sandbox Code Playgroud)


Pet*_*ter 12

解决问题的一个快速解决方案是查看yourappspackage/build/intermediates/explosion-aar/com.android.support/appcompat -v7/res/drawable/for abc_edit_text_material.xml并将该xml文件复制到drawable文件夹中.然后,您可以从此选择器内更改9个补丁文件的颜色,以匹配您的首选项.


Pac*_*gmi 9

只需添加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"/>
Run Code Online (Sandbox Code Playgroud)

  • backgroundTint上面的API级别21 (2认同)

Mtl*_*Dev 8

我也被困在这个问题上太久了.

我需要一个适用于v21上下版本的解决方案.

我终于发现了一个非常简单或许不理想但有效的解决方案:只需transparent在EditText属性中设置背景颜色即可.

<EditText
    android:background="@android:color/transparent"/>
Run Code Online (Sandbox Code Playgroud)

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


yww*_*ynm 7

以下是TextInputLayout支持设计库(UPDATED for version 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));
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果你想以编程方式改变颜色,似乎所有上述代码现在都在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);
}
Run Code Online (Sandbox Code Playgroud)


小智 7

对我来说,我修改了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>
Run Code Online (Sandbox Code Playgroud)

这是colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="yellow">#B7EC2A</color>
</resources>
Run Code Online (Sandbox Code Playgroud)

我将android:textCursorDrawable属性取出到@null,我放在editText样式中.当我尝试使用它时,颜色不会改变.

  • 这应该是答案 (2认同)

Sfs*_*han 6

您可以将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>
Run Code Online (Sandbox Code Playgroud)

如果要为聚焦的edittext提供不同的宽度和颜色,请使用选择器替换形状.


小智 5

我使用这种方法用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);
}
Run Code Online (Sandbox Code Playgroud)


RQu*_*ube 5

经过两天的努力,我找到了这个问题的有效解决方案,下面的解决方案对于那些只想更改少量编辑文本、通过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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在 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"/>
Run Code Online (Sandbox Code Playgroud)

添加样式线条

<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>
Run Code Online (Sandbox Code Playgroud)

切换颜色的java代码

myRqubeEditText.setErrorState(true);
myRqubeEditText.setErrorState(false);
Run Code Online (Sandbox Code Playgroud)


小智 5

在 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"/>
Run Code Online (Sandbox Code Playgroud)

哪里BackgroundTint=color有你想要的颜色