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.