วิธีเพิ่มสีของปุ่มโดยทางโปรแกรม


121

ในไลบรารี AppCompat ใหม่เราสามารถย้อมสีปุ่มด้วยวิธีนี้:

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/follow"
    android:id="@+id/button_follow"
    android:backgroundTint="@color/blue_100"
    />

ฉันจะตั้งค่าสีของปุ่มโดยใช้โปรแกรมในรหัสของฉันได้อย่างไร? โดยพื้นฐานแล้วฉันกำลังพยายามใช้การระบายสีตามเงื่อนไขของปุ่มตามข้อมูลที่ผู้ใช้ป้อน


คุณแน่ใจหรือไม่ว่า android: backgroundTint ทำงานบน Pre-Lollipop ฉันทดสอบกับทั้งปุ่มและ ApCompatButton แต่ backgroundTint ดูเหมือนจะใช้งานได้กับ Lollipop เท่านั้น
Sharj

1
โปรดตรวจสอบคำตอบนี้
Amit Vaghela

คำตอบ:


162

ตามเอกสารวิธีการที่เกี่ยวข้องandroid:backgroundTintคือsetBackgroundTintList (รายการ ColorStateList)

อัปเดต

ไปที่ลิงค์นี้เพื่อเรียนรู้วิธีสร้างทรัพยากรรายการสถานะสี

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="#your_color_here" />
</selector>

จากนั้นโหลดโดยใช้

setBackgroundTintList(contextInstance.getResources().getColorStateList(R.color.your_xml_name));

ที่contextInstanceเป็นตัวอย่างของContext


ใช้ AppCompart

btnTag.setSupportButtonTintList(ContextCompat.getColorStateList(Activity.this, R.color.colorPrimary));

ซึ่งไม่ใช่สี แต่เป็น ColorStateList จะใช้ประโยชน์ได้อย่างไร?
Stephane

4
ฉันเข้าใจวิธีการทำตอนนี้ แต่ทำไม Android ไม่อนุญาตให้คุณใช้สีด้วยตนเอง สำหรับทุกสีของทุกปุ่มฉันจะต้องสร้าง xml สำหรับ ColorStateList? ดูเหมือนว่าจะเสียเปล่าสำหรับฉัน
Stephane

2
setBackgroundTintList ต้องการ API 21 แม้ว่าคุณจะเรียกใช้บน AppCompatButton ก็ตาม
Sharj

30
ไลบรารีการสนับสนุน AppCompat มีตัวช่วยแบบคงViewCompat.setBackgroundTintList(View, ColorStateList)ที่ซึ่งสามารถใช้ย้อนกลับไปยัง API 4 ได้ทั้งหมด แต่ใช้ได้กับมุมมองที่ใช้งานTintableBackgroundViewเท่านั้นเช่นAppCompatButton(แทนที่จะเป็นแบบปกติButton)
Jon Adams

1
ตอนนี้การใช้ViewCompat.setBackgroundTintList(View, ColorStateList)ตามที่ @Jon Adams แนะนำนั้นมีเหตุผลมากขึ้นเนื่องจาก View.setSupportButtonTintList ถูก จำกัด ด้วยRestrictToคำอธิบายประกอบ ดูรายละเอียดได้ที่: developer.android.com/reference/android/support/annotation/…
AlexKost

75

คุณสามารถใช้

button.setBackgroundTintList(ColorStateList.valueOf(resources.getColor(R.id.blue_100)));

แต่ฉันขอแนะนำให้คุณใช้การย้อมสีไลบรารีสนับสนุนซึ่งเพิ่งเปิดตัวเมื่อวานนี้:

Drawable drawable = ...;

// Wrap the drawable so that future tinting calls work
// on pre-v21 devices. Always use the returned drawable.
drawable = DrawableCompat.wrap(drawable);

// We can now set a tint
DrawableCompat.setTint(drawable, Color.RED);
// ...or a tint list
DrawableCompat.setTintList(drawable, myColorStateList);
// ...and a different tint mode
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_OVER);

คุณสามารถดูข้อมูลเพิ่มเติมได้ในบล็อกโพสต์นี้ (ดูหัวข้อ "การย้อมสีที่วาดได้")


2
คุณสามารถระบุรหัสที่สมบูรณ์เพื่อตั้งค่าสีโดยใช้วิธี ur ได้หรือไม่?
M. Usman Khan

คำตอบที่ดีที่สุด ... !
Gokul Nath KP

62

ดูเหมือนว่ามุมมองจะมีกลไกของตัวเองสำหรับการจัดการสีดังนั้นจะดีกว่าที่จะใส่รายการสี:

ViewCompat.setBackgroundTintList(
    editText, 
    ColorStateList.valueOf(errorColor));

ใช้วิธีนี้ได้ดีขึ้นมากดังนั้นคุณจึงเข้ากันได้กับ API 4!
xarlymg89

หนึ่งในทางออกที่ดีที่สุด
Atif AbbAsi

21

ในการขยายคำตอบของ dimsuz อย่างเหมาะสมโดยการให้สถานการณ์รหัสจริงโปรดดูข้อมูลโค้ดต่อไปนี้:

    Drawable buttonDrawable = button.getBackground();
    buttonDrawable = DrawableCompat.wrap(buttonDrawable);
    //the color is a direct color int and not a color resource
    DrawableCompat.setTint(buttonDrawable, Color.RED);
    button.setBackground(buttonDrawable);

โซลูชันนี้มีไว้สำหรับสถานการณ์ที่ใช้ drawable เป็นพื้นหลังของปุ่ม ใช้งานได้กับอุปกรณ์รุ่นก่อนอมยิ้มเช่นกัน


@TruptiNasit ดีใจที่ได้ยินเช่นนั้น
Shayne3000

ทำงานให้ฉัน ขอบคุณ.
wesley

1
@wesleyfranks ยินดีต้อนรับค่ะ ดีใจที่ได้ยินว่าได้ผล
Shayne3000


7

คุณเคยลองอะไรแบบนี้ไหม?

button.setBackgroundTintList(getResources().getColorStateList(R.id.blue_100));

โปรดทราบว่า getResources () จะทำงานในกิจกรรมเท่านั้น แต่ก็สามารถเรียกใช้ได้ในทุกบริบทด้วย


คุณสามารถสร้าง xml ตามที่อธิบายไว้ที่นี่developer.android.com/reference/android/content/res/…
Chris K.

ดูเหมือนว่า getColorStateList จะเลิกใช้งาน
cloudsurfin

1
setBackgroundTintList ดูเหมือนจะต้องใช้ API ระดับ 21
Nashe

1
ปุ่ม. setBackgroundTintList (ContextCompat.getColorStateList (บริบท, R.color.blue)); ทำงานให้ฉัน
jesto paul

5

คุณสามารถใช้ DrawableCompat เช่น

public static Drawable setTint(Drawable drawable, int color) {
    final Drawable newDrawable = DrawableCompat.wrap(drawable);
    DrawableCompat.setTint(newDrawable, color);
    return newDrawable;
}

5

สิ่งนี้จัดการได้อย่างง่ายดายในปุ่มวัสดุใหม่จากไลบรารีการออกแบบวัสดุก่อนอื่นให้เพิ่มการอ้างอิง:

implementation 'com.google.android.material:material:1.1.0-alpha07'

จากนั้นใน XML ของคุณใช้สิ่งนี้สำหรับปุ่มของคุณ:

<com.google.android.material.button.MaterialButton
    android:id="@+id/accept"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/i_accept"
    android:textSize="18sp"
    app:backgroundTint="@color/grayBackground_500" />

และเมื่อคุณต้องการเปลี่ยนสีนี่คือรหัสใน Kotlin ซึ่งยังไม่เลิกใช้งานและสามารถใช้ได้ก่อน Android 21:

accept.backgroundTintList = ColorStateList.valueOf(ResourcesCompat.getColor(resources, 
R.color.colorPrimary, theme))

มีสีที่คล้ายกันสำหรับการย้อมสีข้อความหรือไม่?
นักพัฒนา Android

คุณหมายถึงข้อความเป็นปุ่มและคุณต้องการเปลี่ยนสีของพื้นหลังหรือไม่?
Amin Keshavarzian

4

CompoundButtonCompat.setButtonTintList(button, colour)วิธีที่ฉันจัดการเพื่อให้ได้ของเราที่จะทำงานโดยใช้

เพื่อความเข้าใจของฉันสิ่งนี้ใช้งานได้โดยไม่คำนึงถึงเวอร์ชัน Android


3

ฉันมีปัญหาที่คล้ายกัน ฉันต้องการระบายสีพื้นหลังที่วาดได้ซับซ้อนสำหรับมุมมองตามค่าสี (int) ฉันประสบความสำเร็จโดยใช้รหัส:

ColorStateList csl = new ColorStateList(new int[][]{{}}, new int[]{color});
textView.setBackgroundTintList(csl);

โดยที่สีเป็นค่า int แทนสีที่ต้องการ สิ่งนี้แสดงถึง xml ColorStateList อย่างง่าย:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:color="color here"/>
</selector>

หวังว่านี่จะช่วยได้


2
API ขั้นต่ำที่ต้องการระดับ 21
forsberg

คุณก็ใช้ได้ColorStateList.valueOf(ColorInt)
user924

2

สำหรับ ImageButton คุณสามารถใช้:

favoriteImageButton.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

setColorFilter ไม่ได้กำหนดไว้สำหรับปุ่ม
Jérémy

สำหรับ ImageButton
Saurabh Singh

โอเคฉันไม่รู้เรื่องนี้ แต่ OP ขอ Button คุณสามารถแก้ไขคำตอบของคุณโดยใช้รายละเอียดนี้เพื่อให้ฉันสามารถลบการลงคะแนนได้หรือไม่
Jérémy

2

หากคุณกำลังใช้KotlinและMaterial Designคุณสามารถเปลี่ยนสีของคุณได้MaterialButtonดังนี้:

myButton.background.setTintList(ContextCompat.getColorStateList(context, R.color.myColor))

คุณสามารถปรับปรุงให้ดียิ่งขึ้นได้ด้วยการสร้างฟังก์ชันส่วนขยายสำหรับคุณMaterialButtonเพื่อให้คุณอ่านโค้ดได้ง่ายขึ้นและการเข้ารหัสของคุณสะดวกขึ้นเล็กน้อย:

fun MaterialButton.changeColor(color: Int) {
    this.background.setTintList(ContextCompat.getColorStateList(context, color))
}

จากนั้นคุณสามารถใช้ฟังก์ชันของคุณได้ทุกที่ดังนี้:

myButton.changeColor(R.color.myColor)

1

นอกจากคำตอบของShayne3000 แล้วคุณยังสามารถใช้ทรัพยากรสีได้อีกด้วย (ไม่ใช่เฉพาะสี int) Kotlinเวอร์ชัน:

var indicatorViewDrawable = itemHolder.indicatorView.background
indicatorViewDrawable = DrawableCompat.wrap(indicatorViewDrawable)
val color = ResourcesCompat.getColor(context.resources, R.color.AppGreenColor, null) // get your color from resources
DrawableCompat.setTint(indicatorViewDrawable, color)
itemHolder.indicatorView.background = indicatorViewDrawable

0

คำตอบที่แนะนำที่นี่ทำงานไม่ถูกต้องบน Android 5.0 หากรายการสถานะสีตาม XML ของคุณอ้างอิงแอตทริบิวต์ตามธีม .. ตัวอย่างเช่นฉันมีรายการสถานะสี xml ดังนี้:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="?colorPrimary" android:state_enabled="true"/>
    <item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>

การใช้สิ่งนี้เป็น backgroundTint ของฉันจาก xml ใช้งานได้ดีบน Android 5.0 และอื่น ๆ อย่างไรก็ตามหากฉันพยายามตั้งค่านี้ในรหัสเช่นนี้:

(อย่าทำแบบนี้)

myButton.setSupportButtonTintList(ContextCompat.getColorStateList(myButton.getContext(), R.color.btn_tint_primary));

จริงๆแล้วมันไม่สำคัญว่าฉันจะส่งกิจกรรมหรือบริบทของปุ่มไปยังเมธอด ContextCompat.getColorStateList () หรือไม่ทั้งจะไม่ให้รายการสถานะสีที่เหมาะสมกับธีมที่ปุ่มอยู่ภายใน เนื่องจากไม่รองรับการใช้แอ็ตทริบิวต์ธีมในรายการสถานะสีจนกว่า api 23 และ ContextCompat จะไม่ทำอะไรเป็นพิเศษเพื่อแก้ไขสิ่งเหล่านี้ แต่คุณต้องใช้AppCompatResources.getColorStateList ()ซึ่งทำการแยกวิเคราะห์ทรัพยากร / ธีมความละเอียดของตัวเองบนอุปกรณ์ <API 23

คุณต้องใช้สิ่งนี้แทน:

myButton.setSupportBackgroundTintList(AppCompatResources.getColorStateList(myButton.getContext(), R.color.btn_tint_primary));

TLDR: ใช้AppCompatResourcesและไม่ใช่ -ContextCompat- หากคุณต้องการทรัพยากรที่ได้รับการแก้ไขในเวอร์ชัน API ทั้งหมดของ Android

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อที่ดูบทความนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.