การเปลี่ยนสีบรรทัดล่างของ EditText ด้วย appcompat v7


310

ฉันใช้ 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>

ตามแหล่งที่มาของหุ่นยนต์ API 21 EditTexts ด้วยการออกแบบวัสดุที่ดูเหมือนจะใช้และcolorControlActivated colorControlNormalดังนั้นฉันได้พยายามที่จะแทนที่คุณสมบัติเหล่านี้ในการกำหนดรูปแบบก่อนหน้า แต่มันไม่มีผลกระทบ appcompat อาจไม่ได้ใช้งาน น่าเสียดายที่ฉันไม่สามารถหาแหล่งที่มาสำหรับ appcompat รุ่นล่าสุดที่มีการออกแบบวัสดุ


กำหนดธีมของคุณสำหรับการแก้ไขข้อความ
นา

ขอบคุณสำหรับคำแนะนำของคุณ แต่ฉันได้ทำไปแล้ว ฉันได้อัปเดตคำถามเพื่อแสดงสิ่งที่ฉันได้ลองทำไปแล้ว ปัญหาของฉันเกี่ยวกับแอททริบิวที่จะใช้ในรูปแบบของธีมเพื่อเปลี่ยนสีของบรรทัดล่าง edittext เป็นการดีที่ฉันกำลังมองหาวิธีการแก้ปัญหาที่ฉันสามารถระบุสีใน hexa โดยตรง
Laurent

ไม่มีคำตอบใดที่ใช้งานได้สำหรับฉันที่ 4.3 คุณมีวิธีแก้ปัญหาในการทำงานหรือไม่?
Robert Baker

ฉันต้องขยายออกไปAppCompatEditTextอย่างเห็นได้ชัด
EpicPandaForce

คำตอบ:


479

ในที่สุดฉันก็ได้พบทางออก มันก็ประกอบด้วยเอาชนะค่าสำหรับ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>

9
ฉันเห็นสีของเมนูแฮมเบอร์เกอร์ปุ่มย้อนกลับและแถบเลื่อนเปลี่ยนเป็น colorControlNormal
ario

11
สิ่งนี้จะเปลี่ยนสีของบรรทัดล่าง แต่มันก็เปลี่ยนการควบคุมอื่น ๆ เช่นกล่องกาเครื่องหมายปุ่มตัวเลือกอื่น ๆ และมันก็จะเปลี่ยน EditText ทั้งหมดใน Application / Activity ทั้งหมด หากคุณต้องการเปลี่ยนบรรทัดล่างของ EditText เดียว (เช่นเดียวกับฉัน) คุณต้องแทนที่ android: คุณสมบัติพื้นหลังสำหรับ EditText นั้น ไม่มีทางอื่น AFAIK
Emanuel Moecklin

68
หากคุณกำลังใช้ไลบรารีสนับสนุน V22 AppCompat คุณสามารถระบุรูปแบบใน EditText android:theme="@style/Theme.App.Baseที่ชอบ: สิ่งนี้จะช่วยให้มั่นใจว่าสไตล์จะไม่ส่งผลกระทบต่อมุมมองอื่น ๆ ในเค้าโครงของคุณที่คุณไม่ต้องการเปลี่ยน
Alex Lockwood

8
ไม่ได้ทำงานกับ Jelly Bean (4.2) แต่ทำงานกับ Lollipop
Mangesh

3
AppCompatActivityกิจกรรมที่ควรสืบทอดมาจาก Activityมันจะไม่ทำงานถ้ามันสืบทอดมาจาก
Bharathwaaj

187

ฉันรู้สึกเช่นนี้ต้องการคำตอบในกรณีที่ใครบางคนต้องการเปลี่ยนเพียง edittext เดียว ฉันทำแบบนี้:

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

1
แต่ฉันจะรีเซ็ตเป็นพื้นหลังเริ่มต้นได้อย่างไรฉันมีข้อบกพร่องมากมายหลังจากเรียกใช้ editText.getBackground (). resetColorFilter () บน Lollipop?
ultraon

ข้อควรระวัง! การเพิ่มสิ่งนี้อาจทำให้การเปลี่ยนสีของข้อความแก้ไขในแอพทั้งหมด ทดสอบบน Nexus 5 OS 6.0.1
Alex Perevozchykov

1
@AlexPerevozchykov คุณอาจพูดถูก ลองเพิ่ม. mutut () หลังจาก. getBackground () ที่ควรทำ
hordurh

@hordurh ใช่มันเป็นเรื่องที่ผมได้รับข้อเสนอแนะนี้น้อยบิตก่อนหน้านี้ภาพวาดร่วมกันอย่างใดอย่างหนึ่งเพื่อให้สระว่ายน้ำก่อนที่จะเปลี่ยนเราต้องกลายพันธุ์มัน
อเล็กซ์ Perevozchykov

1
ถ้าฉันใช้ edittext มันใช้งานได้ แต่วิธีนี้ใช้ไม่ได้กับ edittext ที่ใช้ร่วมกันกับแอพบน lollipop คุณรู้ฉันจะแก้ไขปัญหาได้อย่างไร
เซลิน

145

ในขณะที่การแก้ปัญหา Laurentsถูกต้องมันมาพร้อมกับข้อบกพร่องบางอย่างที่อธิบายไว้ในการแสดงความคิดเห็นตั้งแต่ไม่เพียง แต่บรรทัดล่างของEditTextได้รับการย้อมสี แต่ปุ่มย้อนกลับของToolbar, CheckBoxesฯลฯ รวมทั้ง

โชคดีv22.1ของappcompat-v7การแนะนำให้รู้จักความเป็นไปได้ใหม่ ๆ ตอนนี้เป็นไปได้ที่จะกำหนดธีมเฉพาะให้กับมุมมองเดียวเท่านั้น ส่งตรงจากการเปลี่ยนแปลง :

เลิกใช้งานแอพ: ธีมสำหรับ Toolbar สไตล์ ตอนนี้คุณสามารถใช้ android: theme สำหรับแถบเครื่องมือบน 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"/>

1
ฉันไม่คิดว่ามันจำเป็น colorControlNormalหากไม่มีคำนำหน้า Android ให้ใช้วิธี appcompat ในการแต้มสีวิดเจ็ตในขณะที่ส่วนนำหน้าใช้กับวิธีการของระบบและจะมีเฉพาะในอุปกรณ์ API 21+ เท่านั้น
ย้อนกลับ

อืมฉันได้ทดสอบอุปกรณ์อมยิ้มของฉันและมันจะไม่ย้อมสีที่กำหนดเองเว้นแต่ว่าคุณจะใช้มันในรูปแบบ v21 พร้อมกับ Android namespace ด้วย
2968401

ฉันใช้22.2.0เวอร์ชันของ AppCompat แต่เคล็ดลับนี้ใช้ไม่ได้ :(
Shajeel Afzal

1
การใช้ <item name = "colorAccent"> # 000000 </item> ทำงานให้ฉันแทน colorControlNormal
MikeOscarEcho

เหมาะที่จะเปลี่ยนข้อความแก้ไขเพียงหนึ่งเดียวในแอป! (สิ่งที่ฉันต้องการ! ขอบคุณ)
Romain Barbier

99

สิ่งนี้สามารถเปลี่ยนแปลงได้ใน XML โดยใช้:

สำหรับการอ้างอิง API> = ใช้งานร่วมกันได้ 21:

android:backgroundTint="@color/blue"

สำหรับ API แบบย้อนกลับที่ใช้งานได้ <21:

app:backgroundTint="@color/blue"

10
ใช่ แต่ใช้ได้กับ Android API เวอร์ชัน 21+ เท่านั้น (kitkat & lolipop) อาจลองสร้างโซลูชันที่เข้ากันได้แบบย้อนหลัง
DaMachk

12
เพียงใช้backgroundTint="@color/blue"แทนandroid:backgroundTint="@color/blue"การสนับสนุนที่รองรับแบบย้อนหลังได้
Kishan Vaghela

11
@ KishanVaghela แทนที่จะใช้android:backgroundTint="@color/blue"ใช้app:backgroundTint="@color/blue"เพื่อสนับสนุนอุปกรณ์ pre-Lollipop ขอบคุณสำหรับความคิดเห็นของคุณ!
blueware

2
@blueware หากคุณต้องการใช้อย่างมีสไตล์เราไม่จำเป็นต้องใช้ "แอพ"
Kishan Vaghela

เพิ่ม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.1, 25.1.1, 25.2.0สำหรับอุปกรณ์ <21> 21 และมันยังคงทำงาน กรุณาตรวจสอบการสาธิตนี้ง่ายdrive.google.com/file/d/0B_poNaia6t8kSzU3bDFVazRSSDA/... ฉันไม่รู้ว่าทำไมรหัสนี้ใช้ไม่ได้สำหรับคุณดังนั้นโปรดแจ้งให้เราทราบ ขอบคุณ
ฟาน Van Linh

@Renjith ขอโทษที่ตอบช้าโปรดตรวจสอบความคิดเห็นของฉันข้างต้น
ฟาน Van Linh

คุณจะรีเซ็ตสีเป็นค่าเริ่มต้นด้วยรหัสนี้ได้อย่างไร
Neph

35

คำตอบที่ได้รับการยอมรับนั้นเป็นพื้นฐานของสไตล์มากกว่าเล็กน้อย แต่สิ่งที่มีประสิทธิภาพมากที่สุดคือการเพิ่มแอตทริบิวต์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 ใช้สำหรับการย้อมสีวิดเจ็ตทั่วทั้งแอพและควรใช้เพื่อความสม่ำเสมอ


8
@Tomasz ไม่ต้องการ API 21+ เพราะธีมหลักคือ AppCompat ซึ่งลงไปที่ API 7
TanmayP

Ughhh ขอบคุณสำหรับสิ่งนี้ฉันใช้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


@ powder366 คุณสามารถโพสต์ธีมหลักของแอพได้หรือไม่
blueware

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

2
@ powder366, ลองอันนี้: <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">และมันควรจะทำงาน
blueware

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

สิ่งนี้ไม่สะดวกถ้าตัวควบคุมที่ต่างกันต้องการสีที่ต่างกัน
Julius

12

วิธีแก้ปัญหาอย่างรวดเร็วสำหรับปัญหาของคุณคือค้นหา yourappspackage / build / intermediates / exploded-aar / com.android.support / appcompat-v7 / res / drawable / สำหรับ abc_edit_text_material.xml และคัดลอกไฟล์ xml ในโฟลเดอร์ drawable ของคุณ จากนั้นคุณสามารถเปลี่ยนสีของไฟล์แพทช์ 9 ตัวจากภายในตัวเลือกนี้เพื่อให้ตรงกับความต้องการของคุณ


9

มันง่ายมากเพียงแค่เพิ่มแอตทริบิวต์ในของคุณandroid:backgroundTintEditText

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
backgroundTint เหนือ API leve 21
Ashwin H

ViewCompat.setBackgroundTintList (editText, ColorStateList.valueOf (Color.YELLOW))
Arst

1
app:backgroundTint="@color/blue"ใช้งานได้กับทุกระดับ api .. แม้ว่าจะด้วยเหตุผลใดก็ตามมันยังคงเปลี่ยนเป็นสีที่แตกต่างเมื่อเลือก XD
EpicPandaForce

8

นี่คือส่วนหนึ่งของซอร์สโค้ดของTextInputLayoutในไลบรารีการออกแบบสนับสนุน ( UPDATED สำหรับเวอร์ชัน 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

@shahzain ali ขีดเส้นใต้ของ EditText เป็นพื้นหลัง มันหายไปถ้าคุณตั้งค่าเป็นโมฆะ และ thats ทำไม backgroundTint จะทำงาน ( แต่มันจะไม่เปลี่ยนสีเมื่อเปิดใช้งาน)
nyconing

7

สำหรับฉันฉันปรับเปลี่ยนทั้ง AppTheme และค่า color.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 เมื่อฉันลองใช้สิ่งนี้สีจะไม่เปลี่ยน


2
นี่ควรเป็นคำตอบ
Mina Samy

ทำงานเหมือนจับใจ ขอบคุณ
DäñishShärmà

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>

แทนที่รูปร่างด้วยตัวเลือกหากคุณต้องการระบุความกว้างและสีที่แตกต่างกันเพื่อเน้น edittext


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 โดยที่ไม่มี 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);
}

มีตัวระบุที่คล้ายกันเพื่อเข้าถึงบรรทัดล่างของ EditText อย่างง่ายหรือไม่?
Rémi P

4

หากคุณต้องการเปลี่ยนบรรทัดล่างโดยไม่ใช้สีของแอพใช้บรรทัดเหล่านี้ในธีมของคุณ:

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

ฉันไม่รู้วิธีแก้ปัญหาอื่น


4

ฉันทำงานหาทางแก้ไขปัญหานี้หลังจาก 2 วันของการต่อสู้ด้านล่างโซลูชันนี้เหมาะสำหรับผู้ที่ต้องการเปลี่ยนข้อความแก้ไขเพียงไม่กี่ตัวเท่านั้นเปลี่ยนสี / สลับสีด้วยรหัสจาวาและต้องการแก้ไขปัญหาพฤติกรรมที่แตกต่างกันในเวอร์ชั่นของระบบปฏิบัติการ เนื่องจากการใช้เมธอด 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) และปัญหาได้รับการแก้ไขทันที ปรากฎว่าหากคุณใช้งานจริงAppCompatEditTextมันก็จะเคารพaccentColorจากธีมของคุณ (ดังที่กล่าวไว้ในความคิดเห็นหลายข้อด้านบน) และไม่จำเป็นต้องกำหนดค่าเพิ่มเติม


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 นี้น่ากลัวมาก


และวิธีการใช้งานคืออะไร? setBackgroundTintList? มันต้องใช้ API 21
CoolMind

setSupportBackgroundTintListสำหรับ API เวอร์ชันเก่า
Ankit Popli

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.