Cách thêm màu nút theo chương trình


118

Trong thư viện AppCompat mới, chúng ta có thể tô màu nút theo cách này:

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

Làm cách nào để đặt màu của nút theo chương trình trong mã của tôi? Về cơ bản, tôi đang cố gắng triển khai màu có điều kiện của nút dựa trên một số thông tin nhập của người dùng.


Bạn có chắc chắn android: backgroundTint đang hoạt động trên Pre-Lollipop không? Tôi kiểm tra với cả Button và ApCompatButton nhưng backgroundTint dường như chỉ hoạt động trên Lollipop.
Sharj

1
Vui lòng kiểm tra câu trả lời này .
Amit Vaghela,

Câu trả lời:


161

Theo tài liệu , phương pháp liên quan đến android:backgroundTintsetBackgroundTintList (danh sách ColorStateList)

Cập nhật

Theo liên kết này để biết cách tạo Tài nguyên Danh sách Trạng thái Màu.

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

sau đó tải nó bằng cách sử dụng

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

nơi contextInstancelà một thể hiện của mộtContext


sử dụng AppCompart

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

không phải là một màu mà là một ColorStateList. Làm thế nào để tận dụng điều đó?
Stephane

4
Tôi biết cách làm điều đó ngay bây giờ, cảm ơn, nhưng tại sao Android không cho phép bạn chỉ sử dụng màu theo cách thủ công? Đối với mỗi màu của mọi nút tôi có, tôi sẽ phải tạo xml cho ColorStateList? Điều đó có vẻ như là một sự lãng phí đối với tôi
Stephane

2
setBackgroundTintList cần API 21 ngay cả khi bạn gọi nó trên AppCompatButton.
Sharj

29
Thư viện hỗ trợ AppCompat cung cấp một trình trợ giúp tĩnh: ViewCompat.setBackgroundTintList(View, ColorStateList)có thể được sử dụng tất cả các cách trở lại API 4. Nhưng nó chỉ hoạt động cho các dạng xem triển khai TintableBackgroundView, chẳng hạn AppCompatButton(thay vì thông thường Button).
Jon Adams

1
Giờ đây, việc sử dụng ViewCompat.setBackgroundTintList(View, ColorStateList), như @Jon Adams đã đề xuất, thậm chí còn có ý nghĩa hơn vì View.setSupportButtonTintList bị hạn chế với RestrictTochú thích. Thông tin chi tiết tại đây: developer.android.com/reference/android/support/annotation/…
AlexKost

75

Bạn đã có thể sử dụng

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

Nhưng tôi khuyên bạn nên sử dụng thư viện hỗ trợ pha màu có thể vẽ vừa được phát hành ngày hôm qua:

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);

Bạn có thể tìm thêm trong bài đăng trên blog này (xem phần "Pha màu có thể vẽ")


2
u có thể cung cấp mã hoàn chỉnh để đặt màu bằng phương pháp ur?
M. Usman Khan

Câu trả lời tốt nhất...!
Gokul Nath KP

60

Có vẻ như các chế độ xem có cơ chế riêng để quản lý màu, vì vậy tốt hơn sẽ được đưa vào danh sách màu:

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

Tốt hơn nhiều khi sử dụng nó theo cách này, vì vậy bạn có được khả năng tương thích ngược từ API 4!
xarlymg89

một trong những giải pháp tốt nhất.
Atif AbbAsi

20

Để mở rộng đúng câu trả lời của dimsuz bằng cách cung cấp một tình huống mã thực, hãy xem đoạn mã sau:

    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);

Giải pháp này dành cho trường hợp có thể vẽ được sử dụng làm nền của nút. Nó cũng hoạt động trên các thiết bị tiền Lollipop.


@TruptiNasit Rất vui khi biết điều đó.
Shayne3000

Đã làm cho tôi. Cảm ơn bạn.
wesley franks

1
@wesleyfranks Không có chi. Vui mừng khi nghe nó làm việc.
Shayne3000

7

Bạn đã thử một cái gì đó như thế này?

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

lưu ý rằng getResources () sẽ chỉ hoạt động trong một hoạt động. Nhưng nó cũng có thể được gọi trên mọi ngữ cảnh.


Bạn có thể tạo một xml như được mô tả tại đây: developer.android.com/reference/android/content/res/…
Chris K.

getColorStateList dường như không được dùng nữa.
cloudurfin

1
setBackgroundTintList dường như đòi hỏi mức API 21
Nashe

1
cái nút. setBackgroundTintList (ContextCompat.getColorStateList (ngữ cảnh, R.color.blue)); làm việc cho tôi
jesto paul

6

đây là cách để làm điều đó trong kotlin:

view.background.setTint(ContextCompat.getColor(context, textColor))

cảm ơn, nó hoạt động tốt!
Stoica Mircea

5

Bạn có thể sử dụng DrawableCompat, ví dụ:

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

5

điều này có thể dễ dàng xử lý trong Nút Vật liệu mới từ thư viện material design, trước tiên, hãy thêm phần phụ thuộc:

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

thì trong XML của bạn, hãy sử dụng cái này cho nút của bạn:

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

và khi bạn muốn thay đổi màu, đây là mã trong Kotlin, Mã này không bị phản đối và có thể được sử dụng trước Android 21:

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

Có cái nào tương tự cho chính màu văn bản không?
nhà phát triển android

ý bạn là văn bản dưới dạng một nút và bạn muốn thay đổi màu nền?
Amin Keshavarzian

4

Cách tôi quản lý để làm cho công việc của tôi là sử dụng CompoundButtonCompat.setButtonTintList(button, colour).

Theo sự hiểu biết của tôi, điều này hoạt động bất kể phiên bản Android.


3

Tôi đã có một vấn đề tương tự. Tôi muốn tô màu một nền phức tạp có thể vẽ được cho một chế độ xem dựa trên giá trị màu (int). Tôi đã thành công bằng cách sử dụng mã:

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

Trong đó màu là giá trị int đại diện cho màu được yêu cầu. Điều này đại diện cho ColorStateList xml đơn giản:

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

Hi vọng điêu nay co ich.


2
Yêu cầu tối thiểu API cấp 21
forsberg

bạn có thể chỉ cần sử dụngColorStateList.valueOf(ColorInt)
user924 Ngày

2

Đối với ImageButton, bạn có thể sử dụng:

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

setColorFilter không được xác định cho Buttons
Jérémy

Đó là, đối với ImageButton.
Saurabh Singh

Ồ được rồi, tôi không biết về nó. Nhưng OP đang yêu cầu Nút. Bạn có thể chỉnh sửa câu trả lời của mình với chi tiết này để tôi có thể xóa phiếu phản đối của mình không?
Jérémy

2

Nếu bạn đang sử dụng KotlinMaterial Design, bạn có thể thay đổi màu của bạn MaterialButtonnhư thế này:

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

Bạn có thể cải thiện nó tốt hơn nữa bằng cách tạo một chức năng mở rộng cho mã của bạn MaterialButtonđể làm cho mã của bạn dễ đọc hơn và mã của bạn thuận tiện hơn một chút:

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

Sau đó, bạn có thể sử dụng chức năng của mình ở mọi nơi như sau:

myButton.changeColor(R.color.myColor)

1

Ngoài câu trả lời của Shayne3000 , bạn cũng có thể sử dụng tài nguyên màu (không chỉ là màu int). Phiên bản 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

Câu trả lời được đề xuất ở đây không hoạt động đúng trên android 5.0 nếu danh sách trạng thái màu dựa trên XML của bạn tham chiếu đến các thuộc tính theo chủ đề. Ví dụ: tôi có danh sách trạng thái màu xml như sau:

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

Sử dụng nó làm backgroundTint từ xml của tôi hoạt động tốt trên android 5.0 và mọi thứ khác. Tuy nhiên, nếu tôi cố gắng đặt điều này trong mã như thế này:

(Đừng làm điều này)

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

Thực ra không có vấn đề gì nếu tôi chuyển Activity hoặc ngữ cảnh của nút sang phương thức ContextCompat.getColorStateList (), cả hai đều không cung cấp cho tôi danh sách trạng thái màu thích hợp đối với chủ đề mà nút đó ở trong. Điều này là do việc sử dụng các thuộc tính chủ đề trong danh sách trạng thái màu không được hỗ trợ cho đến api 23 và ContextCompat không thực hiện bất kỳ điều gì đặc biệt để giải quyết những điều này. Thay vào đó, bạn phải sử dụng AppCompatResources.getColorStateList () để phân tích cú pháp tài nguyên / phân giải thuộc tính chủ đề của riêng nó trên các thiết bị <API 23.

Thay vào đó, bạn phải sử dụng cái này:

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

TLDR: sử dụng AppCompatResources chứ không phải -ContextCompat- nếu bạn cần tài nguyên theo chủ đề đã giải quyết trên tất cả các phiên bản API của android.

Để biết thêm thông tin về chủ đề, hãy xem bài viết này .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.