Android getResources (). getDrawable () เลิกใช้ API 22


700

ด้วย Android API 22 ใหม่getResources().getDrawable()เลิกใช้แล้ว getDrawable()ตอนนี้วิธีที่ดีที่สุดคือการใช้เพียง

มีอะไรเปลี่ยนแปลง


คุณสามารถระบุคำถามได้ไหม? มันถูกต้องแล้วที่เมธอดgetDrawable (int id)ของคลาสResourcesนั้นเลิกใช้แล้ว ตอนนี้คุณควรใช้วิธีการgetDrawable (int id, Resources.Theme theme)กับพารามิเตอร์ชุดรูปแบบใหม่
รหัสลิง

1
ContextCompat.getDrawable (บริบท, R.color.color_name)
Ashokchakravarthi Nagarajan

คุณสามารถตรวจสอบการโพสต์บล็อกของฉันในเรื่องนี้สำหรับคำอธิบายอย่างละเอียดเพิ่มเติมเกี่ยวกับสาเหตุที่ทั้งสองResources#getDrawable(int)และResources#getColor(int)ถูกคัดค้าน
Alex Lockwood

1
Google ควรทำการแก้ไขอย่างรวดเร็วสำหรับแต่ละฟังก์ชันที่เลิกใช้แล้ว ฉันโพสต์เกี่ยวกับที่นี่: code.google.com/p/android/issues/detail?id=219495
นักพัฒนา Android

คำตอบ:


1028

คุณมีตัวเลือกบางอย่างที่จะจัดการกับการคัดค้านนี้ด้วยวิธีที่ถูกต้อง (และการพิสูจน์ในอนาคต ) ขึ้นอยู่กับชนิดของ drawable ที่คุณกำลังโหลด:


A) drawable พร้อมคุณสมบัติของชุดรูปแบบ

ContextCompat.getDrawable(getActivity(), R.drawable.name);

คุณจะได้รับ Drawable สไตล์เป็นชุดรูปแบบกิจกรรมของคุณสั่ง นี่อาจเป็นสิ่งที่คุณต้องการ


B) drawable ที่ไม่มีแอตทริบิวต์ของธีม

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

คุณจะได้รับ drawable unstyled ของคุณแบบเก่า หมายเหตุ: ResourcesCompat.getDrawable()จะไม่เลิก!


EXTRA) drawable พร้อมกับคุณสมบัติของธีมจากธีมอื่น

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);

แอปของฉันขัดข้องโดยใช้ข้อเสนอแนะ B ไม่ชอบการโทร Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null);
FractalBob

ฉันประกาศด้วยวิธีนี้: โมฆะสาธารณะคงที่ setImageButtonEnabled (บริบท ctxt เปิดใช้งานบูลีนรายการ ImageButton, ไอคอน int intResId) {item.setEnabled (เปิดใช้งาน); drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null); ไอคอน Drawable = เปิดใช้งานหรือไม่ originalIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (ไอคอน); } และเรียกมันเช่นนี้: Utility.setImageButtonEnabled (getContext (), false, back, R.drawable.arrow_left);
FractalBob

แม่นยำยิ่งขึ้นดูเหมือนว่าการขัดข้องจะเกิดขึ้นเพราะไอคอนของฉันเป็นแบบเวกเตอร์
FractalBob

1
รุ่น xamarin: ResourcesCompat.GetDrawable (ทรัพยากร, Resource.Drawable.name, null);
ไบรอัน

ฉันจะเพิ่มหนึ่งคำต่อไปที่คุณ ContextCompat.getColor (บริบทสี) นอกจากนี้ยังสามารถช่วยให้คุณ ...
BertKing

746

แก้ไข: ดูโพสต์บล็อกของฉันในเรื่องสำหรับคำอธิบายที่สมบูรณ์มากขึ้น


คุณควรใช้รหัสต่อไปนี้จากไลบรารีการสนับสนุนแทน:

ContextCompat.getDrawable(context, R.drawable.***)

ใช้วิธีนี้เทียบเท่ากับการโทร:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

ในฐานะของ API 21 คุณควรใช้getDrawable(int, Theme)วิธีการแทนgetDrawable(int)เนื่องจากจะช่วยให้คุณสามารถดึงวัตถุที่วาดได้ที่เกี่ยวข้องกับรหัสทรัพยากรเฉพาะสำหรับความหนาแน่น / ธีมของหน้าจอที่กำหนด โทรเลิกใช้วิธีการจะเทียบเท่ากับการโทรgetDrawable(int)getDrawable(int, null)


8
ฉันคิดว่า OP ยังหมายถึงgetDrawable (int id)วิธีการContextเรียน นี่เป็นเช่นเดียวกับgetResources().getDrawable(id, getTheme());และยังใช้ API ใหม่
รหัสลิง

9
ตามเอกสารระดับนาที 21 API getDrawable(int, Resources.Theme)ที่จำเป็นต้องใช้
เจ้าชาย

@Prince วิธีการที่ถูกเพิ่มเข้ามาใน API 21 แต่มันก็ไม่เลิกจนกว่า API 22. :)
อเล็กซ์ล็อควู้ด

Android doc ยังแนะนำให้ใช้Context :: getDrawable (int) methodแต่เนื่องจากมีการแนะนำใน API 21 เท่านั้นดูเหมือนว่า ContextCompat เป็นตัวเลือกที่ดีที่สุด
goRGon

คำตอบนี้ใช้ไม่ได้กับไฟล์. svg ในเวอร์ชันที่เก่ากว่า API 21 มีข้อบกพร่องในไลบรารี
Jorge Rodríguez

141

แทนที่บรรทัดนี้: getResources().getDrawable(R.drawable.your_drawable)

กับ ResourcesCompat.getDrawable(getResources(), R.drawable.your_drawable, null)

แก้ไข

ResourcesCompatเลิกใช้แล้วในตอนนี้ แต่คุณสามารถใช้สิ่งนี้:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(นี่thisคือบริบท)

สำหรับรายละเอียดเพิ่มเติมตามลิงค์นี้: ContextCompat


2
นั่นแสดงว่าตอนนี้เช่นกัน: plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Xyaren

ดูลิงค์นี้โปรด: developer.android.com/reference/android/support/v4/content/… , int)
vincent091

2
ไม่ได้พูดในลิงค์ที่ResourcesCompatเลิกใช้แล้ว มันควรจะทำงานได้ดี
Jacob R

สิ่งที่จะเขียนใน "drawable ของคุณ" ถ้าฉันต้องการที่จะใส่ภาพไปยังมุมมองรายการในการคลิกรายการที่เก็บไว้ใน drawable
0x0001

29

getResources().getDrawable() เลิกใช้แล้วใน API ระดับ 22 ตอนนี้เราต้องเพิ่มธีม:

getDrawable (int id, ธีม Resources.Theme) (เพิ่มในระดับ API 21)

นี่คือตัวอย่าง:

myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));

นี่คือตัวอย่างวิธีการตรวจสอบสำหรับรุ่นที่ใหม่กว่า:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));
   } else { 
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage));
}

Build.VERSION_CODES.LOLLIPOP is API 21ดังนั้นไม่ควรจะเป็นนี้if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)หรือif (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? ไม่เป็นไร. จากด้านล่าง "มีการเพิ่มวิธีการใน API 21 แต่ไม่เลิกใช้จนกว่าจะถึง API 22. :)"
Mark Cramer

2

คุณสามารถใช้ได้

ContextCompat.getDrawable(getApplicationContext(),R.drawable.example);

ที่ทำงานสำหรับฉัน


การใช้บริบทของแอปพลิเคชันเพื่อโหลดข้อผิดพลาดที่วาดได้เวกเตอร์บน lollipop ก่อน การแก้ไขใด ๆ สำหรับเรื่องนี้?
muthuraj

1
@muthuraj ฉันจำการทดสอบของฉันสำหรับรหัสด้วยกรณี lollipop ไม่ได้ แต่คุณสามารถลอง getActivity () หรือ getResources () แทนได้แล้วนั่นเป็นไปได้ดีกับรหัสของคุณหรือไม่
Dasser Basyouni

ฉันใช้รูปแบบ MVVM และฉันจำเป็นต้องขยาย drawable ภายใน ViewModels ซึ่งไม่มีบริบทของกิจกรรม มีเพียงบริบทแอปพลิเคชัน นั่นคือสิ่งที่ปัญหาของฉันคือ
muthuraj

1

เป็นเพียงตัวอย่างของวิธีที่ฉันแก้ไขปัญหาในอาร์เรย์เพื่อโหลด listView หวังว่าจะช่วยได้

 mItems = new ArrayList<ListViewItem>();
//    Resources resources = getResources();

//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.az_lgo), getString(R.string.st_az), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.ca_lgo), getString(R.string.st_ca), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.co_lgo), getString(R.string.st_co), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.az_lgo, null), getString(R.string.st_az), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.ca_lgo, null), getString(R.string.st_ca), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.co_lgo, null), getString(R.string.st_co), getString(R.string.all_nums)));

1

ลองสิ่งนี้:

public static List<ProductActivity> getCatalog(Resources res){
    if(catalog == null) {
        catalog.add(new Product("Dead or Alive", res
                .getDrawable(R.drawable.product_salmon),
                "Dead or Alive by Tom Clancy with Grant Blackwood", 29.99));
        catalog.add(new Product("Switch", res
                .getDrawable(R.drawable.switchbook),
                "Switch by Chip Heath and Dan Heath", 24.99));
        catalog.add(new Product("Watchmen", res
                .getDrawable(R.drawable.watchmen),
                "Watchmen by Alan Moore and Dave Gibbons", 14.99));
    }
}

ในขณะที่รหัสนี้อาจตอบคำถาม แต่มีบริบทเพิ่มเติมเกี่ยวกับสาเหตุและ / หรือวิธีการที่รหัสนี้ตอบคำถามช่วยปรับปรุงมูลค่าระยะยาว
โดนัลด์ดั๊


1

getDrawable (int drawable)เลิกใช้แล้วใน API ระดับ 22 สำหรับการอ้างอิงดูลิงค์นี้นี้

ตอนนี้เพื่อแก้ไขปัญหานี้เราต้องส่งคอนสตรัคเตอร์ใหม่พร้อมกับ id เช่น: -

getDrawable(int id, Resources.Theme theme)

สำหรับแนวทางแก้ไขให้ทำดังนี้: -

ใน Java: -

ContextCompat.getDrawable(getActivity(), R.drawable.name);   

หรือ

 imgProfile.setImageDrawable(getResources().getDrawable(R.drawable.img_prof, getApplicationContext().getTheme()));

ใน Kotlin: -

rel_week.background=ContextCompat.getDrawable(this.requireContext(), R.color.colorWhite)

หรือ

 rel_day.background=resources.getDrawable(R.drawable.ic_home, context?.theme)

หวังว่านี่จะช่วยคุณได้ขอบคุณ


เป็นมูลค่าการกล่าวขวัญที่ getDrawable (DrawableRes int id, Theme Theme) สามารถโยนข้อยกเว้นหากไม่พบทรัพยากรในขณะที่ getDrawable (บริบทบริบท, int id) เป็นโมฆะจึงต้องส่งคืนด้วย Drawable? ใน Kotlin
Pitos

0

en api ระดับ 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));

คุณควรระบุบริบทเพิ่มเติมอีกเล็กน้อยรอบคำตอบของคุณ
Nicolas Grenié

0

ตอนนี้คุณต้องใช้สิ่งนี้

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
        //
    } else {
        //
    }

การติดตามโค้ดบรรทัดเดียวเพียงพอแล้วทุกอย่างจะดูแลโดย ContextCompat.getDrawable

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)

0

สำหรับบางคนที่ยังคงมีปัญหานี้เพื่อแก้ไขแม้หลังจากใช้ข้อเสนอแนะของเธรดนี้ (ฉันเคยเป็นเช่นนั้น) เพิ่มบรรทัดนี้ในคลาสแอปพลิเคชันของคุณวิธี onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

ตามที่แนะนำ ที่นี่และที่นี่บางครั้งจำเป็นต้องเข้าถึงเวกเตอร์จากแหล่งข้อมูลโดยเฉพาะเมื่อคุณจัดการกับรายการเมนู ฯลฯ


0

ใน Kotlin คุณสามารถใช้ส่วนขยาย

fun Context.getMyDrawable(id : Int) : Drawable?{

    return  ContextCompat.getDrawable(this, id)
}

จากนั้นใช้เช่น

context.getMyDrawable(R.drawable.my_icon)

-2

Build.VERSION_CODES.LOLLIPOP ควรเปลี่ยนเป็น BuildVersionCodes.Lollipop เช่น:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder, Context.Theme);
} else {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder);
}

ไม่ใช่BuildVersionCodesคลาสเฉพาะของซามารินใช่ไหม
Ted Hopp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.