appcompat v7でEditTextボトムラインの色を変更する


310

appcompat v7を使用して、Android 5以下で一貫した外観を実現しています。それはかなりうまくいきます。ただし、EditTextの最下線の色とアクセントカラーを変更する方法がわかりません。出来ますか?

カスタム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のソースが見つかりません。


エディットテキストのためのあなたのテーマ定義
ミーナル

提案をありがとうございますが、私はすでにそうしています。質問を更新して、すでにやろうとしたことを示しました。私の問題は、テーマスタイルでedittextの最下線の色を変更するために使用する属性についてです。理想的には、ヘキサで色を直接指定できるソリューションを探しています。
Laurent

これらの答えはどれも、4.3では機能しません。有効な解決策はありますか?
Robert Baker

AppCompatEditTextどうやら、延長しなければならなかった。
EpicPandaForce 2016年

回答:


479

最後に、私は解決策を見つけました。それは単にの値をオーバーライドから成りcolorControlActivatedcolorControlHighlightそして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>

9
メニューのハンバーガー、戻るボタン、スクロールバーの色がcolorControlNormalに変更されたことがわかります。
アリオ2014年

11
これにより、下の線の色が変更されますが、チェックボックス、ラジオボタンなどの他のすべてのコントロールも変更されます。また、アプリケーション/アクティビティ全体のすべてのEditTextも変更されます。単一のEditTextの最終行を変更したい場合は(私と同じように)、そのEditTextのandroid:backgroundプロパティをオーバーライドする必要があります。私の知る限り、他に方法はありません。
Emanuel Moecklin、2015

68
AppCompat v22サポートライブラリを使用している場合は、次のようにEditTextでテーマを指定できますandroid:theme="@style/Theme.App.Base。これにより、スタイルが、変更したくないレイアウトの他のビューに影響を与えないようになります。
Alex Lockwood 2015

8
Jelly Bean(4.2)では機能しませんでしたが、Lollipopで機能しました
Mangesh

3
アクティビティはから継承する必要がありAppCompatActivityます。から継承した場合は機能しませんActivity
Bharathwaaj

187

誰かが単一の編集テキストを変更したい場合に備えて、これには答えが必要だと感じました。私はそれをこのようにします:

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

1
しかし、どうすればデフォルトの背景にリセットできますか?LollipopでeditText.getBackground()。resetColorFilter()を呼び出した後、多くのバグが発生しますか?
ウルトラオン2015年

注意!これを追加すると、すべてのアプリでeditTextの色が変わる可能性があります。Nexus 5.OS 6.0.1でテスト済み。
Alex Perevozchykov 2016

1
@AlexPerevozchykovあなたは正しいかもしれません。.getBackground()の後に.mutate()を追加してみてください。それでうまくいくはずです。
hordurh 2016

@hordurhはい、それはそれでした、私は少し前にこの提案を受けました、ドロアブルは1つのプールを共有するため、変更する前に変更する必要があります
Alex Perevozchykov

1
edittextを使用する場合、それは機能しますが、この方法はlollipopのapp compat edittextでは機能しません。どうすれば問題を解決できますか?
セリン

145

一方でLaurentsソリューションが正しいの一番下の行だけでなくので、コメントで説明したように、それはいくつかの欠点が付属してEditText着色ますが、の戻るボタンToolbarCheckBoxesなどにも。

幸運なことにv22.1appcompat-v7いくつかの新しい可能性が導入されました。特定のテーマを1つのビューにのみ割り当てることができるようになりました。変更ログから直接

ツールバーのスタイル設定のためのapp:themeの非推奨の使用。すべての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>

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/MyEditTextTheme"/>

1
これは必要ないと思います。colorControlNormalandroid接頭辞がない場合はappcompatメソッドを使用してウィジェットに色を付けますが、接頭辞がある場合はシステムメソッドにフォールバックします。これはAPI 21以降のデバイスでのみ使用できます。
2015年

うーん、ロリポップデバイスでテストしましたが、Android名前空間を使用してv21スタイルで実装しない限り、カスタムカラーに色付けされません。
user2968401

22.2.0AppCompatのバージョンを使用していますが、このトリックは機能しません:(
Shajeel Afzal

1
colorControlNormalの代わりに<item name = "colorAccent">#000000 </ item>を使用するとうまくいきました。
MikeOscarEcho

アプリで編集テキストを1つだけ変更するのに最適です!(まさに私が必要としていたものです。ありがとうございます)
Romain Barbier

99

これは、以下を使用してXMLで変更できます。

参照API> = 21の互換性を使用する場合:

android:backgroundTint="@color/blue"

下位API <21の互換性を使用する場合:

app:backgroundTint="@color/blue"

10
はい、ただし、これはAndroid APIバージョン21以降(kitkat&lolipop)でのみ機能します。おそらく、下位互換性のあるソリューションを作成しようとするでしょう。
DaMachk、2015

12
下位互換性サポートのbackgroundTint="@color/blue"代わりに使用android:backgroundTint="@color/blue"する
Kishan Vaghela

11
@KishanVaghelaをandroid:backgroundTint="@color/blue"使用app:backgroundTint="@color/blue"する代わりに、Lollipop以前のデバイスをサポートするために使用します。コメントをありがとうございます!
ブルーウェア2016

2
@bluewareスタイルで使用したい場合は、「app」を使用する必要はありません。
Kishan Vaghela 16

tools:ignore="MissingPrefix"赤い下線が下にある場合は追加app:backgroundTint="<your color>"
Moses Aprico

47

以下は、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
}

ここに画像の説明を入力してください

それが役に立てば幸い


@CoolMind返信が遅れて申し訳ありません。私は、サポートライブラリに再びこのコードをチェックする必要があり24.2.125.1.125.2.0デバイス<21> 21のために、それはまだ取り組んでいます。この簡単なデモをご覧くださいdrive.google.com/file/d/0B_poNaia6t8kSzU3bDFVazRSSDA/…。このコードが機能しない理由はわかりません。お知らせください。ありがとう
ファンヴァンリン2017

@Renjith返信が遅くなって申し訳ありません。上記の私のコメントをチェックしてください
ファンヴァンリン

このコードでどのように色をデフォルトにリセットしますか?
Neph

35

受け入れられた答えはスタイルごとに少し多いですが、最も効率的なことは、次のように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属性は、アプリ全体でウィジェットの色付けに使用されるため、一貫性を保つために使用する必要があります


8
@Tomasz親のテーマがAppCompatでAPI 7になるため、API 21以降は必要ありません
TanmayP

うーん。このおかげで、私はname="android:colorAccent"誤って使用していました
Jules

29

使用している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);
    }

この命の恩人、それはよく知っているではありません素晴らしい、恥ものです
pt123

下に移動して、デザインライブラリ23.2.0に対する私の回答を参照してください。この方法は現在役に立たない。
ywwynm

21

使用する:

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

これは、+ 21だけでなく、Lollipop以前のデバイスもサポートします


@ powder366、アプリのメインテーマを投稿できますか?
ブルーウェア2016年

1
<style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar">
powder366

2
@ powder366、これを試してください:<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">そして、それはうまくいくはずです
ブルーウェア

19

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


できます!質問が尋ねるように、それはスタイル/テーマで解決されるべきであり、これは正しい答えでなければなりません。
Ninja

同意する。それは世界的なソリューションであるため、これが正しい答えでなければなりません
Santacrab

異なるコントロールが異なる色を必要とする場合、これは不便です。
ジュリアス

12

問題の簡単な解決策の1つは、yourappspackage / build / intermediates / exploded-aar / com.android.support / appcompat-v7 / res / drawable /でabc_edit_text_material.xmlを探し、そのxmlファイルをドローアブルフォルダーにコピーすることです。次に、このセレクター内から9つのパッチファイルの色を変更して、好みに合わせます。


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

2
APIレベル21以上のbackgroundTint
Ashwin H

ViewCompat.setBackgroundTintList(EDITTEXT、ColorStateList.valueOf(Color.YELLOW))
ARST

1
app:backgroundTint="@color/blue"すべてのapiレベルで動作します。ただし、何らかの理由で、XDを選択したときに依然として別の色に変わります
EpicPandaForce

8

以下は、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);
}

AppCompatDrawableManagerとは何ですか?setBackgroundはAPI 16.必要です
CoolMind

8

私もこの問題に長い間こだわっていました。

v21の上下両方のバージョンで機能するソリューションが必要でした。

最終的に、非常に単純でおそらく理想的ではないが効果的な解決策を発見しtransparentました。EditTextプロパティで背景色をに設定するだけです。

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

これが誰かの時間の節約になることを願っています。


1
これは背景色全体を変更しており、下線の色のみを変更したいと考えています。
shahzain ali 2016

@shahzain ali EditTextの下線は背景です。これをnullに設定すると消えます。そして、それがbackgroundTintが機能する理由です(ただし、アクティブにしても色は変わりません)
nyconing

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>

これがcolors.xmlです

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

editTextスタイル内に配置したandroid:textCursorDrawable属性を@nullに取り出しました。使ってみても色が変わらない。


2
これが答えになるはずです
Mina Samy

魅力のように働いた。おかげで
デンマーク・シャルマ

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>

フォーカスされた編集テキストに異なる幅と色を提供する場合は、形状をセレクターに置き換えます。


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

BackgroundTint=colorご希望の色の場所


5

このメソッドを使用して、他のドローアブルなしで、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);
}

単純なEditTextの最終行にアクセスするための同様の識別子はありますか?
レミP

4

アプリの色を使用せずにボトムラインを変更したい場合は、テーマでこれらのラインを使用してください:

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

別の解決策を知りません。


4

私は2日間の闘争の後にこの問題の実用的な解決策を考え出しました。以下の解決策は、編集テキストのみをいくつか変更し、Javaコードを使用して色を変更/切り替え、OSバージョンでの異なる動作の問題を克服したいユーザーに最適です。 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);

2

私はこの問題に完全に困惑しました。私はこのスレッドや他のスレッドですべてを試しましたが、どうしても下線の色をデフォルトの青以外に変更できませんでした。

私はついに何が起こっているのかを理解しました。android.widget.EditText新しいインスタンスを作成するときに(誤って)使用していました(ただし、残りのコンポーネントはappcompatライブラリからのものでした)。使うべきだったandroid.support.v7.widget.AppCompatEditText。と交換new EditText(this)new AppCompatEditText(this) て問題がすぐに解決しました。結局のところ、実際にを使用している場合はAppCompatEditTextaccentColor(上記のいくつかのコメントで言及されているように)テーマのが尊重され、追加の構成は必要ありません。


2

これは、すべての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"/>

2

動的の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に関するこのSOの回答は素晴らしいです。


そして、どの方法を使用するのですか?setBackgroundTintList?これは、API 21.必要です
CoolMind

setSupportBackgroundTintList古いAPIのverisonsため。
Ankit Popli 2017

0

app:backgroundTint以下のAPIレベル21 を追加します。それ以外の場合はを使用します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"/>

-2

必要に応じてこのメソッドを変更してください。これは私のために働いた!

  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());
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.