ฉันจะรับรหัสทรัพยากรของรูปภาพได้อย่างไรถ้าฉันรู้ชื่อ [ซ้ำ]


133

ฉันจะรับรหัสทรัพยากรของรูปภาพได้อย่างไรถ้าฉันรู้ชื่อ (ใน Android)


หากคุณต้องการทำกับkotlinโปรดดู: stackoverflow.com/a/52568692/1631967
aminography

คำตอบ:


270

ด้วยสิ่งนี้:

String mDrawableName = "myappicon";
int resID = getResources().getIdentifier(mDrawableName , "drawable", getPackageName());

10
ขอบคุณที่ช่วยฉันหาวิธีแก้ปัญหาที่คล้ายกัน! ฉันจะใช้getResources().getIdentifier(name, "id", getPackageName());เพื่อรับ ID ของ ImageButton (เหมือนที่คุณทำกับ R.id.name)
Select0r

42
โปรดทราบว่าชื่อที่ดึงได้ไม่ควรมีนามสกุลเช่น ".png"
larham1

1
สิ่งที่เกิดขึ้นในตัวแปรname? ฉันต้องการค้นหารหัสของปุ่มที่มีข้อมูลอ้างอิงที่ฉันรู้ในกรณีของฉันคือbutton1
John Watson

1
getResource()และgetPackageName()แสดงข้อผิดพลาด cannot resolve method
Srujan Barai

@Srujan Barai getResource()และgetPackageName()เป็นวิธีการจากกิจกรรม
The Berga

29

คุณยังสามารถลองสิ่งนี้:

try {
    Class res = R.drawable.class;
    Field field = res.getField("drawableName");
    int drawableId = field.getInt(null);
}
catch (Exception e) {
    Log.e("MyTag", "Failure to get drawable id.", e);
}

ฉันได้คัดลอกซอร์สโค้ดนี้จาก URL ด้านล่าง จากการทดสอบในหน้านี้เร็วกว่า getIdentifier () 5 เท่า ฉันยังพบว่ามันสะดวกและใช้งานง่ายกว่า หวังว่ามันจะช่วยคุณเช่นกัน

ลิงก์: การดึงทรัพยากรใน Android แบบไดนามิก


2
อาจเร็วกว่านี้ แต่ฉันพบว่าอาจทำให้คุณมีปัญหาได้หากคุณใช้ proguard สิ่งนี้ไม่ได้ผลอย่างน้อยสำหรับฉัน
Pedro Rainho

การจับข้อยกเว้นทั่วไปเป็นความคิดที่ไม่ดีอย่างยิ่ง นอกจากนี้โปรดทราบว่าหากไม่มีการอ้างอิงที่ยากสำหรับการดึงข้อมูล Proguard อาจปรับการอ้างอิงให้เหมาะสมที่สุดเนื่องจากไม่เชื่อว่าจะถูกนำไปใช้ที่ใดก็ได้
Paul Lammertsma

ฉันเข้าใจแล้ว :) คุณหมายความว่าในระหว่างการเพิ่มประสิทธิภาพการเปลี่ยนแปลง drawableName และทรัพยากรไม่พบโดยใช้วิธีนี้ถ้าฉันถูก :)
VSB

1
@VSB: หากความคิดเห็นล่าสุดของคุณเป็นการตอบสนองต่อความคิดเห็นของ Paul Lammertsma ด้านบนทันที: ไม่เขาหมายความว่า Proguard ไม่รู้ว่านี่เป็นการอ้างอิงถึงทรัพยากรและอาจลบทรัพยากรออกโดยเชื่อว่าไม่ได้ใช้
ToolmakerSteve

เมื่อคุณใช้ xxxxhdpi, xxhdpi ฯลฯ วิธีนี้จะมีประโยชน์น้อยลง
ใครบางคน

11

ตัวอย่างทรัพยากรระบบสาธารณะ:

// this will get id for android.R.drawable.ic_dialog_alert
int id = Resources.getSystem().getIdentifier("ic_dialog_alert", "drawable", "android");

แจ้งเตือน

อีกวิธีหนึ่งคือการอ้างอิงเอกสารสำหรับคลาสandroid.R.drawable


1
@Milaaaad คุณหมายถึงอะไร?
naXa

หมายความว่าฉันสับสนกับทรัพยากรในโค้ดและฉันใช้มันในคลาสที่ไม่ใช่กิจกรรม
Milaaaad

1
@Milaaaad วิธีนี้ใช้สำหรับทรัพยากรระบบ ไม่ได้ขึ้นอยู่กับบริบท
naXa

10

คุณสามารถใช้ฟังก์ชันนี้เพื่อรับรหัสทรัพยากร:

public static int getResourseId(Context context, String pVariableName, String pResourcename, String pPackageName) throws RuntimeException {
    try {
        return context.getResources().getIdentifier(pVariableName, pResourcename, pPackageName);
    } catch (Exception e) {
        throw new RuntimeException("Error getting Resource ID.", e)
    } 
}


ดังนั้นหากคุณต้องการรับรหัสทรัพยากรแบบวาดได้คุณสามารถเรียกใช้เมธอดดังนี้:

getResourseId(MyActivity.this, "myIcon", "drawable", getPackageName());

(หรือจากส่วนย่อย):

getResourseId(getActivity(), "myIcon", "drawable", getActivity().getPackageName());


สำหรับString Resource ID คุณสามารถเรียกมันได้ดังนี้:

getResourseId(getActivity(), "myAppName", "string", getActivity().getPackageName());

ฯลฯ ...


ข้อควรระวัง : มันพ่น RuntimeException หากไม่พบรหัสทรัพยากร อย่าลืมกู้คืนอย่างถูกต้องในการผลิต

อ่านนี่


4
ฉันคิดว่าคุณต้องลบออกstaticมิฉะนั้นgetResources()จะไม่ได้ผล
Richard Le Mesurier

@Richard Le Mesurier คุณอธิบายได้ไหมว่าทำไม? ขอบคุณ.
Veer

1
@ Leo.Han ในขณะที่ฉันแสดงความคิดเห็นContextนั้นไม่สามารถใช้ได้ การแก้ไขคือการลบstaticและย้ายไปเป็นContext(เช่นActivityหรือApplication); หรือการแก้ไขทางเลือกคือสิ่งที่โจนาธานทำในการแก้ไขของเขาซึ่งก็คือการส่งต่อContextไปยังวิธีการ
Richard Le Mesurier

1
@Richard Le Mesurier ฉันตรวจสอบประวัติการแก้ไขแล้วตอนนี้ก็เหมือนกับที่คุณพูดขอบคุณสำหรับการตอบกลับที่กรุณาของคุณหลังจากผ่านไปหลายปี :)
Veer

0

อีกสถานการณ์หนึ่งที่ฉันพบ

สตริง imageName = "สวัสดี" จากนั้นเมื่อส่งผ่านไปยังฟังก์ชัน getIdentifier เป็นอาร์กิวเมนต์แรกชื่อจะส่งผ่านชื่อที่มีการยกเลิกสตริงว่างและจะคืนค่าศูนย์เสมอ ส่ง imageName.substring นี้ (0, imageName.length () - 1)

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