getColor (int id) tidak digunakan lagi di Android 6.0 Marshmallow (API 23)

719

The Resources.getColor(int id)Metode telah usang.

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

Apa yang harus saya lakukan?

araks
sumber
26
Gunakan ContextCompat.getColor (konteks, R.color.color_name)
Ashokchakravarthi Nagarajan
Dengan metode yang disebutkan di atas: getColor (konteks, R.color.your_color); Tidak jelas bagaimana cara mendapatkan "konteks". Itu tidak akan berhasil dengan hanya menempatkan konteks di sana dalam kasus saya, android studio 3.2. Saya menemukan ini bekerja untuk saya. .setTextColor (Color.RED).
Harry

Jawaban:

1347

Mulai dari Android Support Library 23,
metode getColor () baru telah ditambahkan ContextCompat.

Penjelasannya dari JavaDoc resmi:

Mengembalikan warna yang terkait dengan ID sumber daya tertentu

Mulai dari M, warna yang dikembalikan akan ditata untuk tema Konteks yang ditentukan.


Jadi, panggil saja :

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


Anda dapat memeriksa ContextCompat.getColor() kode sumber di GitHub .

araks
sumber
1
Ini terlihat seperti solusinya, tetapi apa yang harus kita lakukan ketika kita mendapatkan kesalahan "Haruskah lulus warna yang diselesaikan alih-alih id sumber daya di sini"? Sejauh yang saya tahu itu mungkin karena Lint tidak mengenali API baru dari Perpustakaan Dukungan, jadi mungkin hanya menambahkan anotasi @SuppressWarnings ("ResourceAsColor") adalah cara untuk pergi? Saya tidak begitu menyukainya.
Stan
1
Hai @Stan, bisakah Anda memberikan potongan kode dengan pemanggilan metode yang memicu Lint "ResourceAsColor"?
araks
"int color = ContextCompat.getColor (ini, R.color.orange);" dan kemudian "span = new ForegroundColorSpan (color);". Kata yang digarisbawahi dalam warna merah adalah "warna" di mana saya meneruskannya ke "ForegroundColorSpan ()" baru.
Stan
1
@MonicaLabbao oh ... maaf, saya salah mengerti komentar Anda! :)
araks
3
ContextCompatApi23 kesalahan tanda ini mengandaikan Anda referensi ContextCompat
Webserveis
499

tl; dr:

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

Penjelasan:

Anda perlu menggunakan ContextCompat.getColor () , yang merupakan bagian dari Perpustakaan Dukungan V4 (ini akan bekerja untuk semua API sebelumnya).

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

Jika Anda belum menggunakan Perpustakaan Dukungan, Anda harus menambahkan baris berikut ke dependenciesarray di dalam aplikasi Anda build.gradle(catatan: itu opsional jika Anda sudah menggunakan perpustakaan appcompat (V7) ):

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

Jika Anda peduli dengan tema, dokumentasi menetapkan bahwa:

Mulai dari M, warna yang dikembalikan akan ditata untuk tema Konteks yang ditentukan

Melvin
sumber
4
Ini harus dipilih sebagai jawaban yang benar. Karena di tautan yang diberikan Android Docs, tertulis " Mulai M, warna yang dikembalikan akan ditata untuk tema Konteks yang ditentukan. "
Bugs Happen
1
kompilasi 'com.android.support:appcompat-v7:23.0.1'
G O'Rilla
@ G O'Rilla Seperti yang Anda lihat dalam dokumentasi, ContextCompatkelasnya berasal dari SupportV4. AppcompatV7 berfungsi juga karena mengandalkan SupportV4. Seperti yang mereka katakan pada dokumentasi Support Perpustakaan , 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.. Jadi masuk akal untuk tidak memasukkan AppcompatV7jawaban.
Melvin
1
Terima kasih @Melvin, ini adalah contoh saya jika digunakan: int colorTwitterBlue = ContextCompat.getColor (this, R.color.color_twitter_blue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_NEGATIVE) .setTextColor (colorTwitterBlue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_POSITIVE) .setTextColor (colorTwitterBlue);
Lara Ruffle Coles
1
@Melvin. Apa sebenarnya artinya 'warna akan ditata sesuai dengan tema Konteks yang ditentukan'. Kedengarannya seperti seseorang dapat menentukan warna yang berbeda untuk id warna yang sama tergantung pada temanya. Bagaimana tepatnya ini dilakukan?
RobertoCuba
47

Saya tidak ingin menyertakan pustaka Dukungan hanya untuk getColor , jadi saya menggunakan sesuatu seperti

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

Saya kira kode harus bekerja dengan baik, dan yang usang getColortidak dapat hilang dari API <23.

Dan inilah yang saya gunakan di 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);
Alex Vang
sumber
4
Melihat kode sumber, beginilah cara perpustakaan pendukung melakukannya. Saya menargetkan API> = 21 jadi saya tidak ingin memasukkan tabung penuh untuk beberapa baris ini. Perhatikan bahwa Anda dapat menekan peringatan di Android Studio dengan menambahkan "// penghentian inspeksi noins" di atas panggilan yang sudah usang. Dan gunakan konteks Aktivitas, bukan konteks Aplikasi, atau Anda mungkin kehilangan informasi tema.
personne3000
2
Ini harus menjadi jawaban yang benar, meskipun pustaka dukungan dapat menjadi lebih banyak pilihan bukti di masa depan, saya setuju bahwa jika ini adalah satu-satunya alasan Anda memasukkan pustaka dukungan untuk, Anda sebaiknya menyertakan beberapa baris ini.
anthonymonori
30

Di Android Marshmallow banyak metode yang usang.

Misalnya, untuk mendapatkan penggunaan warna

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

Juga untuk menggunakan drawable

ContextCompat.getDrawable(context, R.drawable.drawble_name);
Ashokchakravarthi Nagarajan
sumber
3
dari mana konteks variabel berasal? apakah saya harus menginisialisasi? Saya tidak bisa membuatnya bekerja. Bagi saya sepertinya Androind memiliki jalan yang panjang; itu membuat f f mind saya betapa saya berjuang untuk mendapatkan warna dari sumber xml !! Wow
ColdTuna
29

Untuk semua pengguna Kotlin di luar sana:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}
Paul Spiesberger
sumber
Sebenarnya seharusnya begitu val color = ContextCompat.getColor(context, R.color.colorPrimary). Variabel "itu" bisa berupa apa saja, tetapi harus berupa Konteks .
Scott Biggs
itdalam hal ini context, karena saya gunakan context?.let {untuk memeriksa apakah contexttidak nol. Fungsi getColor()hanya menerima konteks yang bukan nol. Baca lebih lanjut di sini tentang letdan bagaimana menggunakannya: kotlinlang.org/docs/reference/scope-functions.html#let
Paul Spiesberger
4

Di RecyclerView Anda di 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
    }
}
Irvin Joao
sumber
1

Gunakan getColor(Resources, int, Theme)metode dari ResourcesCompatdari Perpustakaan Dukungan Android.

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

Saya pikir itu mencerminkan pertanyaan Anda lebih baik daripada getColor(Context, int)yang ContextCompatsejak Anda tanyakan Resources. Sebelum API level 23, tema tidak akan diterapkan dan metode ini memanggil, getColor(int)tetapi Anda tidak akan memiliki peringatan yang sudah usang. Temanya juga mungkin null.

Pedro
sumber
1
Jika Anda memberikan nol sebagai argumen Tema, warna yang dikembalikan TIDAK akan ditata untuk tema saat ini. Jadi itu mungkin salah.
araks
1

Jika Anda tidak perlu sumber dayanya, gunakan parseColor(String):
Color.parseColor("#cc0066")

N. Osil
sumber
1

Jika mingetColor() Anda saat ini. Level API 23, Anda cukup menggunakan seperti yang kami gunakan untuk mendapatkan sumber daya string dengan getString():

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

Anda dapat membatasi untuk Tingkat API di bawah 23:

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

tetapi untuk membuatnya sederhana, Anda dapat melakukan seperti di bawah ini sebagai jawaban yang diterima:

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

Dari Sumber Daya .

Dari ContextCompat AndroidX .

Dari Dukungan ContextCompat

Blasanka
sumber
0

Saya juga frustrasi. Kebutuhan saya sangat mudah. Yang saya inginkan adalah warna ARGB dari sumber daya, jadi saya menulis metode statis sederhana.

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;
}
steven smith
sumber