web-dev-qa-db-ja.com

Appcompat v7でEditTextのボトムラインカラーを変更する

私は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の資料によると、マテリアルデザインのあるEditTextはcolorControlActivatedcolorControlNormalを使っているようです。したがって、前のスタイル定義でこれらのプロパティをオーバーライドしようとしましたが、効果はありません。おそらくappcompatはそれを使用しません。残念ながら、私は材料設計を伴うappcompatの最後のバージョンのためのソースを見つけることができません。

295
Laurent

最後に、私は解決策を見つけました。それは単にあなたのedittextスタイルではなくあなたのアプリテーマ定義の中のcolorControlActivatedcolorControlHighlightそしてcolorControlNormalの値をオーバーライドすることから成ります。それから、あなたが望むどんな活動にもこのテーマを使うことを考えてください。以下はその例です。

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

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

editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);
182
hordurh

Laurentsの解決策 は正しいのですが、コメントに記載されているように、EditTextの一番下の行だけでなくToolbarCheckBoxesの戻るボタンも着色されるので、いくつかの欠点があります。

幸いなことにv22.1appcompat-v7はいくつかの新しい可能性をもたらしました。特定のテーマを1つのビューにのみ割り当てることが可能になりました。 チェンジログ から直接

ツールバーのスタイル設定のためのapp:themeの廃止予定。 現在使用できます Android:すべてのAPIレベル7以降のデバイス上のツールバーのテーマ、およびAPIレベル11以降のデバイス上のAndroid:theme support すべてのウィジェット用 _ 。

そのため、グローバルテーマに希望の色を設定する代わりに、新しい色を作成して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"/>
140
reVerse

参考のため。これはxmlで次のように変更することができます。

Android:backgroundTint="@color/blue"
91
l-l

これが 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
}

enter image description here

それが助けを願っています

45
Phan Van Linh

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

34
TanmayP

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);
    }
28
Felipe Conde

つかいます:

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

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

19
blueware
<!-- 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>
17
Ashwin H

あなたの問題に対する一つの素早い解決策は、abc_edit_text_material.xmlのためにyourappspackage/build /仲介物/展開されたaar/com.Android.support/appcompat-v7/res/drawable /を調べてそしてあなたのdrawableフォルダーにそのxmlファイルをコピーすることです。その後、あなたの好みに合うように、このセレクターの中から9つのパッチファイルの色を変えることができます。

12
Peter

EditTextAndroid: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"/>
9

私もこの問題にあまりにも長く立ち往生していました。

私はv21の上と下の両方のバージョンで動作するソリューションを必要としていました。

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

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

私はこれが誰かが時間を節約することを願っています。

7
Mtl Dev

これはサポートデザインライブラリのTextInputLayoutのソースコードの一部です( バージョン23.2.0の場合はUPDATED )。これは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);
}
7
ywwynm

これを実現するには、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>

フォーカスされたエディットテキストの幅と色を変えたい場合は、シェイプをセレクタに置き換えます。

6
Sfseyhan

私は、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);
}
5
user2721167

私はこの問題の実用的な解決策を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);
4
RQube

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

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

私は他の解決策を知りません。

4
rz0

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

4
M.Zanella

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

私はようやく何が起こっているのか理解しました。新しいインスタンスを作成するときに(誤って)Android.widget.EditTextを使用していました(ただし、残りのコンポーネントはappcompatライブラリからのものです)。私はAndroid.support.v7.widget.AppCompatEditTextを使ったはずです。 new EditText(this)new AppCompatEditText(this)に置き換えたところ、問題は即座に解決しました。実際にAppCompatEditTextを使っているのであれば、それはあなたのテーマからのaccentColorを尊重し(上記のいくつかのコメントで述べられているように)、追加の設定は不要です。

2
mkasberg

これは最も簡単で最も効率的な/再利用可能な/すべての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
Oliver Dixon

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回答は最高です

1
Ankit Popli