Nhận color-int từ tài nguyên màu


447

Có cách nào để lấy color-int từ tài nguyên màu không? Tôi đang cố gắng để có được các thành phần màu đỏ, xanh dương và xanh lục riêng lẻ của một màu được xác định trong tài nguyên (R.color.myColor) để tôi có thể đặt các giá trị của ba tìm kiếm ở một mức cụ thể.

Câu trả lời:


927

Bạn có thể dùng:

getResources().getColor(R.color.idname);

Kiểm tra ở đây về cách xác định màu tùy chỉnh:

http://sree.cc/google/android/defining-custom-colors-USE-xml-in-android

EDIT (1):getColor(int id)hiện không được chấp nhận , nên phải sử dụng:

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

(được thêm vào trong thư viện hỗ trợ 23)

EDIT (2):

Mã bên dưới có thể được sử dụng cho cả trước và sau Marshmallow (API 23)

ResourcesCompat.getColor(getResources(), R.color.your_color, null); //without theme

ResourcesCompat.getColor(getResources(), R.color.your_color, your_theme); //with theme

7
Còn về Android.R.color.some_color :-(
Blundell

17
@Blundell uhh, dunno nếu bạn cần ngay bây giờ nhưng điều này hoạt động android.R.color.some_colorquá tốt, ví dụ: getResources().getColor(android.R.color.holo_blue_bright)(ít nhất, trên API 17)
ataulm

30
getColor () bây giờ bị phản đối, bạn có thể sử dụng: ContextCompat.getColor (bối cảnh, R.color.your_color);
Ricardo

2
Tôi nhận ra bạn không phải là người thực hiện các chỉnh sửa, nhưng sự khác biệt giữa ContextCompatvà là ResourcesCompatgì? Nếu không có sự khác biệt thực tế, sẽ ít khó hiểu hơn nếu bạn loại bỏ một trong số chúng khỏi câu trả lời của bạn.
Suragch

14
Tại sao Google cảm thấy cần phải từ chối một chức năng hoàn toàn tốt cho thư viện nhỏ gọn ứng dụng khủng khiếp đó. Nó hút, có cả hai.
Andrew S

116

Dựa trên Thư viện hỗ trợ Android mới (và bản cập nhật này ), bây giờ bạn nên gọi:

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

Theo tài liệu :

public int getColor (int id)

Phương pháp này không được dùng trong API cấp 23 . Sử dụng getColor (int, Theme) thay thế

Đây là giải pháp tương tự cho getResources().getColorStateList(id):

Bạn phải thay đổi nó như thế này:

ContextCompat.getColorStateList(getContext(),id);

EDIT 2019

Về việc ThemeOverlaysử dụng bối cảnh của quan điểm gần nhất:

val color = ContextCompat.getColor(
  closestView.context,
  R.color.name.color
)

Vì vậy, theo cách này bạn có được màu sắc phù hợp dựa trên ThemeOverlay của bạn.

Đặc biệt cần thiết khi trong cùng một hoạt động bạn sử dụng các chủ đề khác nhau, như chủ đề tối / sáng. Nếu bạn muốn hiểu thêm về Chủ đề và Phong cách, bài nói chuyện này được đề xuất: Phát triển Chủ đề với Phong cách

Nick Butcher - Droidcon Berlin - Phát triển chủ đề với phong cách


10
Đối với những người thắc mắc nên điền gì vào chủ đề trong phương thức mới, Themecó thể được chuyển thành null, vì vậy hãy gọi getColor(R.color.my_color, null)nếu bạn không chắc chắn chủ đề nào sẽ được chuyển vào.
w3bshark

hmm ... đây là những gì mọi người nói nhưng tôi không thể làm cho nó hoạt động được. Tôi có phải khởi tạo bối cảnh không? Hiện tại tôi nhận được "không thể giải quyết biểu tượng 'bối cảnh'"
ColdTuna

Để đảm bảo rằng bạn đang thực hiện đúng, hãy thử gọi nó bên trong onCreate của hoạt động, hơn là để lấy ngữ cảnh bạn cần gọi getContext () hoặc chỉ "này"
Ultimo_m

35

Xác định màu sắc của bạn

giá trị / color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- color int as #AARRGGBB (alpha, red, green, blue) -->
    <color name="orange">#fff3632b</color>
    ...
    <color name="my_view_color">@color/orange</color>

</resources>

Lấy màu int và đặt nó

int backgroundColor = ContextCompat.getColor(context, R.color.my_view_color);
// Color backgroundColor = ... (Don't do this. The color is just an int.)

myView.setBackgroundColor(backgroundColor);

Xem thêm


1
bạn chỉ có thể sử dụng getResources()trong một Activityhoặc Fragment?
Zapnologica

2
@Zapnologica, hãy xem câu trả lời cho câu hỏi này để biết suy nghĩ về việc sử dụng getResources()bên ngoài Hoạt động hoặc Đoạn.
Suragch 8/07/2015

1
@Zapnologica không. getResources()cũng có sẵn dưới dạng API công khai trên mọi nội dung triển khai Bối cảnh và cả trên Chế độ xem.
ataulm

7

Cách tiếp cận tốt nhất

Như @sat trả lời, cách tiếp cận tốt để có được màu sắc là

ResourcesCompat.getColor(getResources(), R.color.your_color, null);

hoặc sử dụng cách dưới đây khi bạn không có quyền truy cập vào getResources()phương pháp.

Context context  = getContext(); // like Dialog class
ResourcesCompat.getColor(context.getResources(), R.color.your_color, null);

Những gì tôi làm là

public void someMethod(){
    ...
    ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);
}

Nó là đơn giản nhất để sử dụng bất cứ nơi nào trong ứng dụng của bạn! Ngay cả trong lớp Util hoặc bất kỳ lớp nào mà bạn không có Ngữ cảnh hoặc getResource ()

Vấn đề (Khi bạn không có Ngữ cảnh)

Khi bạn không có Contextquyền truy cập , như một phương thức trong Utillớp của bạn .

Giả sử phương pháp dưới đây không có ngữ cảnh.

public void someMethod(){
    ...
    // can't use getResource() without Context.
}

Bây giờ bạn sẽ vượt qua Contextnhư một tham số trong phương thức này và sử dụnggetResources().

public void someMethod(Context context){
    ...
    context.getResources...
}

Vì vậy, đây là một giải pháp độc đáo mà bạn có thể truy cập tài nguyên từ bất cứ đâu như thế Util class. Thêm Resourcesvào Applicationlớp của bạn hoặc Tạo một nếu không tồn tại.

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static App mInstance;
    private static Resources res;


    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        res = getResources();
    }

    public static App getInstance() {
        return mInstance;
    }

    public static Resources getResourses() {
        return res;
    }

}

Thêm trường tên vào manifest.xml <applicationthẻ của bạn . (Nếu chưa được thêm)

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Bây giờ bạn tốt để đi. Sử dụng ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);bất cứ nơi nào trong ứng dụng.


5

Tôi đã cập nhật để sử dụng ContextCompat.getColor(context, R.color.your_color);nhưng đôi khi (Trên một số thiết bị / phiên bản Android. Tôi không chắc chắn) gây ra NullPulumEx805iton.

Vì vậy, để làm cho nó hoạt động trên tất cả các thiết bị / phiên bản, tôi quay lại cách làm cũ, trong trường hợp con trỏ null.

try {
    textView.setTextColor(ContextCompat.getColor(getActivity(), R.color.text_grey_dark));
}
catch(NullPointerException e) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        textView.setTextColor(getContext().getColor(R.color.text_grey_dark));
    }
    else {
        textView.setTextColor(getResources().getColor(R.color.text_grey_dark));
    }
}

tại sao không sử dụng phiên bản cũ trong mọi trường hợp hoặc nếu bạn vẫn đang kiểm tra phiên bản, hãy sử dụng API mới Resources.getColor(int, Theme)nếu bạn có thể? Bạn không nên bắt ngoại lệ thời gian chạy.
ataulm

Tôi cho là OCD. ContextCompat, với tôi dường như là cách chứng minh tương lai để làm điều đó, và do đó là cách đúng đắn. Vì vậy, cách tiếp cận của tôi là, làm điều đó đúng cách. Và nếu thất bại (trên các thiết bị cũ hoặc bất cứ điều gì), hãy làm theo cách cũ. Tại sao tôi không nên bắt ngoại lệ khi chạy?
ninjachippie 10/03/2016

1

Để biết thêm thông tin về trường hợp sử dụng khác có thể giúp hiển thị câu hỏi này trong kết quả tìm kiếm, tôi muốn áp dụng alpha cho màu được xác định trong tài nguyên của mình.

Sử dụng câu trả lời đúng của @ sat:

int alpha = ... // 0-255, calculated based on some business logic
int actionBarBackground = getResources().getColor(R.color.actionBarBackground);
int actionBarBackgroundWithAlpha = Color.argb(
        alpha,
        Color.red(actionbarBackground),
        Color.green(actionbarBackground),
        Color.blue(actionbarBackground)
);

1

Tìm thấy một cách dễ dàng hơn mà cũng hoạt động:

Color.parseColor(getString(R.color.idname);

Thật thú vị, không nhận ra bạn có thể lấy màu như một chuỗi theo cách này. Tôi không nghĩ nó dễ hơn, nhưng thật thú vị
ataulm

0

Truy cập màu từ một lớp không hoạt động có thể khó khăn. Một trong những lựa chọn thay thế mà tôi tìm thấy là sử dụng enum. enumcung cấp rất nhiều tính linh hoạt.

public enum Colors
{
  COLOR0(0x26, 0x32, 0x38),    // R, G, B
  COLOR1(0xD8, 0x1B, 0x60),
  COLOR2(0xFF, 0xFF, 0x72),
  COLOR3(0x64, 0xDD, 0x17);


  private final int R;
  private final int G;
  private final int B;

  Colors(final int R, final int G, final int B)
  {
    this.R = R;
    this.G = G;
    this.B = B;
  }

  public int getColor()
  {
    return (R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff);
  }

  public int getR()
  {
    return R;
  }

  public int getG()
  {
    return G;
  }

  public int getB()
  {
    return B;
  }
}


0

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

//example
textView.setTextColor(getColor(R.color.green));
// if context is not available(ex: not in activity) use with context.getColor()

Nếu bạn muốn dưới mức API 23, chỉ cần sử dụng điều này:

textView.setTextColor(getResources().getColor(R.color.green));

Nhưng lưu ý rằng getResources().getColor()không được dùng trong Cấp độ API 23. Trong trường hợp đó, thay thế ở trên bằng:

textView.setTextColor(ContextCompat.getColor(this /*context*/, R.color.green)) //Im in an activity, so I can use `this`

ContextCompat : Trình trợ giúp truy cập các tính năng trongContext

Nếu bạn muốn, bạn có thể ràng buộc SDK_INTnhư dưới đây:

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

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

trong hoạt động

ContextCompat.getColor(actvityname.this, R.color.your_color);

trong mảnh

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

ví dụ:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
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.