getColor (int id) เลิกใช้แล้วใน Android 6.0 Marshmallow (API 23)


718

Resources.getColor(int id)วิธีการได้รับการคัดค้าน

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

ฉันควรทำอย่างไรดี?


26
ใช้ ContextCompat.getColor (บริบท, R.color.color_name)
— Ashokchakravarthi Nagarajan

ด้วยวิธีการดังกล่าวข้างต้น: getColor (บริบท, R.color.your_color); มันไม่ชัดเจนว่าจะได้รับ "บริบท" มันจะไม่ทำงานโดยเพียงแค่ใส่บริบทลงไปในกรณีของฉัน android studio 3.2 ฉันพบว่ามันใช้งานได้สำหรับฉัน .setTextColor (Color.RED)
— แฮร์รี่

คำตอบ:


1347

เริ่มต้นจาก Android สนับสนุนห้องสมุด 23
ใหม่getColor ()ContextCompatวิธีการได้รับการเพิ่ม

คำอธิบายจาก JavaDoc อย่างเป็นทางการ:

ส่งคืนสีที่เกี่ยวข้องกับรหัสทรัพยากรเฉพาะ

เริ่มต้นที่ M สีที่ถูกส่งคืนจะถูกจัดรูปแบบสำหรับธีมของบริบทที่ระบุ


ดังนั้นเพียงโทร :

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


คุณสามารถตรวจสอบContextCompat.getColor() รหัสที่มาบน GitHub


1
ดูเหมือนว่าวิธีแก้ปัญหา แต่เราควรทำอย่างไรเมื่อเราได้รับข้อผิดพลาด "ควรผ่านสีที่แก้ไขแล้วแทนที่จะเป็น id ของทรัพยากรที่นี่" เท่าที่ฉันสามารถบอกได้อาจเป็นเพราะ Lint ไม่รู้จัก API ใหม่ของ Support Library ดังนั้นอาจแค่เพิ่มคำอธิบายประกอบ @SuppressWarnings ("ResourceAsColor") เป็นวิธีการที่จะทำอย่างไร ฉันไม่ชอบมันมาก
— Stan

1
สวัสดี @Stan คุณช่วยระบุรหัสขนาดด้วยการเรียกใช้เมธอดที่เรียกใช้ "ResourceAsColor" Lint ได้หรือไม่
— araks

"int color = ContextCompat.getColor (นี่, R.color.orange);" จากนั้น "span = new ForegroundColorSpan (color);" คำที่ได้รับการขีดเส้นใต้ด้วยสีแดงคือ "color" ที่ฉันส่งผ่านไปยัง "new ForegroundColorSpan ()"
— Stan

1
@MonicaLabbao โอ้ ... ขอโทษฉันเข้าใจผิดความคิดเห็นของคุณ! :)
— araks

3
ContextCompatApi23 ข้อผิดพลาดของเครื่องหมายนี้ทำให้คุณอ้างอิง ContextCompat
— Webserveis

498

TL; DR:

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

คำอธิบาย:

คุณจะต้องใช้ContextCompat.getColor ()ซึ่งเป็นส่วนหนึ่งของ Support V4 Library (ซึ่งจะใช้งานได้กับ API ก่อนหน้านี้ทั้งหมด)

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

หากคุณยังไม่ได้ใช้ห้องสมุดสนับสนุนคุณจะต้องเพิ่มบรรทัดต่อไปนี้ลงในdependenciesอาร์เรย์ภายในแอปของคุณbuild.gradle(หมายเหตุ: เป็นทางเลือกถ้าคุณใช้ไลบรารี appcompat (V7) ):

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

หากคุณสนใจเกี่ยวกับธีมส์เอกสารระบุว่า:

เริ่มต้นที่ M สีที่ถูกส่งคืนจะถูกจัดรูปแบบสำหรับธีมของบริบทที่ระบุ


4
นี่ควรเป็นคำตอบที่ถูกต้อง เพราะในลิงก์ที่ระบุของเอกสาร Android มันบอกว่า " เริ่มต้นในMสีที่ส่งคืนจะถูกจัดรูปแบบสำหรับชุดรูปแบบของบริบทที่ระบุ "
— บักเกิดขึ้น

1
รวบรวม 'com.android.support:appcompat-v7:23.0.1'
— G O'Rilla

@G O'Rilla อย่างที่คุณเห็นในเอกสารประกอบContextCompatคลาสมาจาก SupportV4 AppcompatV7 ทำงานเช่นเดียวกันกับที่ใช้กับ SupportV4 อย่างที่พวกเขากล่าวไว้ในเอกสารสนับสนุนของห้องสมุด , 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.. ดังนั้นจึงไม่ควรใส่AppcompatV7คำตอบ
— เมลวิน

1
ขอบคุณ @Melvin นี่คือตัวอย่างของฉันถ้าใช้: int colorTwitterBlue = ContextCompat.getColor (นี่, R.color.color_twitter_blue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_NEGATIVE) .setTextColor (colorTwitterBlue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_POSITIVE) .setTextColor (colorTwitterBlue);
— Lara Ruffle Coles

1
@Melvin หมายความว่าอะไร 'สีจะถูกจัดรูปแบบตามธีมของบริบทที่ระบุ' เสียงเหมือนสามารถกำหนดสีต่าง ๆ สำหรับรหัสสีเดียวกันขึ้นอยู่กับชุดรูปแบบ สิ่งนี้จะทำอย่างไรกันแน่?
— RobertoCuba

47

ฉันไม่ต้องการรวมไลบรารีการสนับสนุนสำหรับgetColorเท่านั้นดังนั้นฉันจึงใช้สิ่งที่ชอบ

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

ฉันเดาว่ารหัสควรทำงานได้ดีและเลิกใช้แล้วgetColorไม่สามารถหายไปจาก API <23

และนี่คือสิ่งที่ฉันใช้ใน 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
ดูซอร์สโค้ดนี่คือวิธีที่ไลบรารี่สนับสนุนทำ ฉันกำหนดเป้าหมาย API> = 21 ดังนั้นฉันไม่ต้องการรวมไหแบบเต็มสำหรับสองสามบรรทัด โปรดทราบว่าคุณสามารถระงับคำเตือนใน Android Studio ได้โดยเพิ่ม "// noinspection deprecation" ด้านบนการโทรที่ไม่รองรับ และใช้บริบทกิจกรรมไม่ใช่บริบทแอปพลิเคชันหรือคุณอาจสูญเสียข้อมูลชุดรูปแบบ
— personne3000

2
นี่ควรเป็นคำตอบที่ถูกต้องแม้ว่าไลบรารี่สนับสนุนอาจเป็นทางเลือกที่พิสูจน์ได้ในอนาคต แต่ฉันยอมรับว่าหากนี่เป็นเหตุผลเดียวที่คุณมีไลบรารี่สนับสนุนสำหรับคุณ
— anthonymonori

30

ใน Android Marshmallow มีวิธีการมากมายที่เลิกใช้แล้ว

ตัวอย่างเช่นการใช้สี

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

นอกจากนี้เพื่อให้สามารถใช้งานได้

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

3
บริบทของตัวแปรมาจากที่ใด ฉันจะต้องเริ่มต้นมันได้หรือไม่ ฉันไม่สามารถทำงานได้ สำหรับฉันดูเหมือนว่า Androind จะมีทางยาวไป มันพัดใจของฉันเท่าไหร่ฉันพยายามดิ้นรนเพื่อให้ได้สี af จากทรัพยากร xml !! ว้าว
— ColdTuna

29

สำหรับผู้ใช้ Kotlin ทั้งหมด:

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

val color = ContextCompat.getColor(context, R.color.colorPrimary)ที่จริงควรจะเป็น ตัวแปร "มัน" จะเป็นอะไร แต่มันจะต้องมีบริบท
— Scott Biggs

itเป็นในกรณีนี้contextเนื่องจากฉันใช้context?.let {เพื่อตรวจสอบว่าcontextไม่เป็นโมฆะ ฟังก์ชันgetColor()ยอมรับบริบทที่ไม่ใช่ค่าว่างเท่านั้น อ่านเพิ่มเติมได้ที่นี่เกี่ยวกับletวิธีใช้: kotlinlang.org/docs/reference/scope-functions.html#let
— Paul Spiesberger

4

ใน RecyclerView ของคุณใน 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

ใช้getColor(Resources, int, Theme)วิธีการของResourcesCompatจากห้องสมุดสนับสนุน Android

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

ฉันคิดว่ามันสะท้อนให้เห็นถึงคำถามของคุณดีขึ้นกว่าgetColor(Context, int)ของตั้งแต่คุณถามเกี่ยวกับContextCompat Resourcesก่อนที่จะมี API ระดับ 23 ธีมจะไม่ถูกนำไปใช้และวิธีการเรียกใช้ผ่านgetColor(int)แต่คุณจะไม่ได้รับคำเตือนที่เลิกใช้ nullรูปแบบก็อาจจะเป็น


1
หากคุณผ่านค่า null เป็นอาร์กิวเมนต์ของชุดรูปแบบสีที่ส่งคืนจะไม่ถูกจัดรูปแบบสำหรับชุดรูปแบบปัจจุบัน ดังนั้นมันอาจไม่ถูกต้อง
— araks


1

หากนาทีปัจจุบันgetColor()ของคุณ ระดับ API คือ 23 คุณสามารถใช้เหมือนที่เราใช้เพื่อรับทรัพยากรสตริงโดยgetString():

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

คุณสามารถ จำกัด ระดับ API ต่ำกว่า 23:

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

แต่เพื่อให้ง่ายคุณสามารถทำเหมือนคำตอบที่ยอมรับด้านล่าง:

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

จากทรัพยากร

จากContextCompat AndroidX

จากการสนับสนุน ContextCompat


0

ฉันก็ผิดหวังเช่นกัน ความต้องการของฉันตรงไปตรงมามาก สิ่งที่ฉันต้องการก็คือสี ARGB จากแหล่งข้อมูลดังนั้นฉันจึงเขียนวิธีสแตติกแบบง่าย

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