getColor (int id) không dùng nữa trên Android 6.0 Marshmallow (API 23)


718

Các Resources.getColor(int id)phương pháp đã bị phản đối.

@ColorInt
@Deprecated
public int getColor(@ColorRes int id) throws NotFoundException {
    return getColor(id, null);
}

Tôi nên làm gì?


26
Sử dụng ContextCompat.getColor (bối cảnh, R.color.color_name)
Ashokchakravarthi Nagarajan

Với phương pháp này được đề cập ở trên: getColor (bối cảnh, R.color.your_color); Không rõ làm thế nào để có được "bối cảnh". Nó sẽ không hoạt động bằng cách đặt bối cảnh trong trường hợp của tôi, android studio 3.2. Tôi tìm thấy điều này làm việc cho tôi. .setTextColor (Màu.RED).
Harry

Câu trả lời:


1347

Bắt đầu từ Thư viện hỗ trợ Android 23,
một phương thức getColor () mới đã được thêm vào ContextCompat.

Mô tả của nó từ JavaDoc chính thức:

Trả về màu được liên kết với ID tài nguyên cụ thể

Bắt đầu bằng M, màu được trả về sẽ được tạo kiểu cho chủ đề của Ngữ cảnh được chỉ định.


Vì vậy, chỉ cần gọi :

ContextCompat.getColor(context, R.color.your_color);


Bạn có thể kiểm tra ContextCompat.getColor() mã nguồn trên GitHub .


1
Điều này trông giống như giải pháp, nhưng chúng ta phải làm gì khi gặp lỗi "Có nên chuyển màu đã giải quyết thay vì id tài nguyên ở đây" không? Theo như tôi có thể nói có lẽ bởi vì Lint không nhận ra API mới của Thư viện hỗ trợ, vì vậy có lẽ chỉ cần thêm một chú thích @SuppressWarnings ("ResourceAsColor") là cách để đi? Tôi không thích nó lắm.
Stan

1
Xin chào @Stan, bạn có thể vui lòng cung cấp đoạn mã với lệnh gọi phương thức kích hoạt Lint "ResourceAsColor" không?
trả lời 15/03/2016

"int color = ContextCompat.getColor (cái này, R.color.orange);" và sau đó "span = new ForegroundColorSpan (màu);". Từ được gạch chân màu đỏ là "màu" trong đó tôi chuyển từ đó sang "ForegroundColorSpan ()" mới.
Stan

1
@MonicaLabbao oh ... xin lỗi, tôi đã hiểu nhầm ý kiến ​​của bạn! :)
trả lời

3
ContextCompatApi23 lỗi đánh dấu này cho thấy bạn tham khảo ContextCompat
Webserveis

498

tl; dr:

ContextCompat.getColor(context, R.color.my_color)

Giải trình:

Bạn sẽ cần sử dụng ContextCompat.getColor () , một phần của Thư viện V4 hỗ trợ (nó sẽ hoạt động cho tất cả các API trước đó).

ContextCompat.getColor(context, R.color.my_color)

Nếu bạn chưa sử dụng Thư viện hỗ trợ, bạn sẽ cần thêm dòng sau vào dependenciesmảng bên trong ứng dụng của mình build.gradle(lưu ý: tùy chọn nếu bạn đã sử dụng thư viện appcompat (V7) ):

compile 'com.android.support:support-v4:23.0.0' # or any version above

Nếu bạn quan tâm đến các chủ đề, tài liệu chỉ định rằng:

Bắt đầu bằng M, màu được trả về sẽ được tạo kiểu cho chủ đề Ngữ cảnh được chỉ định


4
Điều này nên được chọn là câu trả lời đúng. Bởi vì trong liên kết đã cho của Tài liệu Android, nó có nội dung " Bắt đầu M, màu được trả về sẽ được tạo kiểu cho chủ đề Ngữ cảnh được chỉ định. "
Lỗi xảy ra vào

1
biên dịch 'com.android.support:appcompat-v7:23.0.1'
G O'Rilla

@G O'Rilla Như bạn có thể thấy trong tài liệu, ContextCompatlớp đến từ SupportV4. AppcompatV7 cũng hoạt động vì nó phụ thuộc vào SupportV4. Như họ nói trên tài liệu Thư viện hỗ trợ , This library depends on the v4 Support Library. If you are using Ant or Eclipse, make sure you include the v4 Support Library as part of this library's classpath.. Vì vậy, nó có ý nghĩa không đưa AppcompatV7vào câu trả lời.
Melvin

1
Cảm ơn @Melvin, đây là ví dụ của tôi nếu sử dụng: int colorTwitterBlue = ContextCompat.getColor (this, R.color.color_twitter_blue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_NEGECT) .setTextColor (colorTwitterBlue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_POSITIVE) .setTextColor (colorTwitterBlue);
Lara Ruffle Coles

1
@Melvin. Chính xác thì điều đó có nghĩa là 'màu sẽ được tạo kiểu theo chủ đề của Ngữ cảnh được chỉ định'. Âm thanh như người ta có thể xác định các màu khác nhau cho cùng một id màu tùy thuộc vào chủ đề. Làm thế nào là điều này được thực hiện chính xác?
RobertoCuba

47

Tôi không muốn bao gồm thư viện Hỗ trợ chỉ dành cho getColor , vì vậy tôi đang sử dụng một cái gì đó như

public static int getColorWrapper(Context context, int id) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return context.getColor(id);
    } else {
        //noinspection deprecation
        return context.getResources().getColor(id);
    }
}

Tôi đoán mã sẽ hoạt động tốt và không getColorthể biến mất khỏi API <23.

Và đây là những gì tôi đang sử dụng trong Kotlin:

/**
 * Returns a color associated with a particular resource ID.
 *
 * Wrapper around the deprecated [Resources.getColor][android.content.res.Resources.getColor].
 */
@Suppress("DEPRECATION")
@ColorInt
fun getColorHelper(context: Context, @ColorRes id: Int) =
    if (Build.VERSION.SDK_INT >= 23) context.getColor(id) else context.resources.getColor(id);

4
Nhìn vào mã nguồn, đây chính xác là cách thư viện hỗ trợ thực hiện. Tôi nhắm mục tiêu API> = 21 vì vậy tôi không muốn bao gồm một bình đầy đủ cho một vài dòng này. Lưu ý rằng bạn có thể loại bỏ cảnh báo trong Android Studio bằng cách thêm "// depinspection deprecation" phía trên cuộc gọi không dùng nữa. Và sử dụng bối cảnh Hoạt động, không phải bối cảnh Ứng dụng hoặc bạn có thể mất thông tin chủ đề.
personne3000

2
Đây phải là câu trả lời chính xác, mặc dù thư viện hỗ trợ có thể là sự lựa chọn bằng chứng trong tương lai, tôi đồng ý rằng nếu đây là lý do duy nhất bạn bao gồm thư viện hỗ trợ, tốt hơn hết là bạn nên bao gồm cả hai dòng này.
anthonymousonori 6/11/2016

30

Trong Android Marshmallow, nhiều phương thức không được dùng nữa.

Ví dụ, để có được màu sử dụng

ContextCompat.getColor(context, R.color.color_name);

Ngoài ra để có được sử dụng drawable

ContextCompat.getDrawable(context, R.drawable.drawble_name);

3
bối cảnh biến đổi đến từ đâu? tôi có phải khởi tạo nó không? Tôi không thể có được nó để làm việc. Đối với tôi có vẻ như Androind còn một chặng đường dài để đi; nó thổi vào tâm trí tôi bao nhiêu là tôi đang vật lộn để có được màu af từ tài nguyên xml !! Wow
ColdTuna

29

Đối với tất cả người dùng Kotlin ngoài kia:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}

Thật ra nên như vậy val color = ContextCompat.getColor(context, R.color.colorPrimary). Biến "nó" có thể là bất cứ thứ gì, nhưng nó cần phải là một Ngữ cảnh .
Scott Bigss

ittrong trường hợp này là context, vì tôi sử dụng context?.let {để kiểm tra nếu contextkhông phải là null. Hàm getColor()chỉ chấp nhận một bối cảnh không null. Đọc thêm ở đây về letvà cách sử dụng nó: kotlinlang.org/docs/reference/scope-fifts.html#let
Paul Spiesberger

4

Trong RecyclerView của bạn trong Kotlin

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(t: YourObject, listener: OnItemClickListener.YourObjectListener) = with(itemView) {
        textViewcolor.setTextColor(ContextCompat.getColor(itemView.context, R.color.colorPrimary))
        textViewcolor.text = t.name
    }
}

1

Sử dụng getColor(Resources, int, Theme)phương pháp của ResourcesCompatThư viện hỗ trợ Android.

int white = new ResourcesCompat().getColor(getResources(), R.color.white, null);

Tôi nghĩ rằng nó phản ánh câu hỏi của bạn tốt hơn so với câu hỏi getColor(Context, int)của ContextCompatbạn Resources. Trước API cấp 23, chủ đề sẽ không được áp dụng và phương thức gọi đến getColor(int)nhưng bạn sẽ không có cảnh báo không dùng nữa. Chủ đề cũng có thể được null.


1
Nếu bạn chuyển null thành đối số Chủ đề, màu được trả về sẽ KHÔNG được tạo kiểu cho chủ đề hiện tại. Vì vậy, nó có thể không chính xác.
araks


1

Nếu tối thiểu hiện tạigetColor() của bạn . Cấp API là 23, bạn chỉ có thể sử dụng như chúng tôi đang sử dụng để lấy tài nguyên chuỗi bằng cách getString():

//example
textView.setTextColor(getColor(R.color.green));
// if `Context` is not available, use with context.getColor()

Bạn có thể ràng buộc cho các cấp API dưới 23:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}

nhưng để đơn giản, bạn có thể thực hiện như dưới đây như câu trả lời được chấp nhận:

textView.setTextColor(ContextCompat.getColor(context, R.color.green))

Từ Tài nguyên .

Từ ContextCompat AndroidX .

Từ hỗ trợ ContextCompat


0

Tôi cũng nản lòng. Nhu cầu của tôi rất đơn giản. Tất cả những gì tôi muốn là màu ARGB từ các tài nguyên, vì vậy tôi đã viết một phương thức tĩnh đơn giản.

protected static int getARGBColor(Context c, int resId)
        throws Resources.NotFoundException {

    TypedValue color = new TypedValue();
    try {
        c.getResources().getValue(resId, color, true);
    }
    catch (Resources.NotFoundException e) {
        throw(new Resources.NotFoundException(
                  String.format("Failed to find color for resourse id 0x%08x",
                                resId)));
    }
    if (color.type != TYPE_INT_COLOR_ARGB8) {
        throw(new Resources.NotFoundException(
                  String.format(
                      "Resourse id 0x%08x is of type 0x%02d. Expected TYPE_INT_COLOR_ARGB8",
                      resId, color.type))
        );
    }
    return color.data;
}
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.