Android, mendapatkan ID sumber daya dari string?

158

Saya perlu memberikan ID sumber daya ke metode di salah satu kelas saya. Perlu menggunakan id yang ditunjuk oleh referensi dan juga membutuhkan string. Bagaimana cara terbaik saya mencapai ini?

Sebagai contoh:

R.drawable.icon

Saya perlu mendapatkan ID integer ini, tetapi saya juga perlu akses ke string "ikon".

Akan lebih baik jika semua yang saya harus sampaikan ke metode adalah string "ikon".

Hamid
sumber
apakah mungkin dengan cara yang sama untuk mendapatkan file yang disimpan ke penyimpanan internal? Saya punya masalah karena saya harus menyediakan array id daripada lokasi ke galeri saya (pikir itu adaptor) .. terima kasih
Ewoks
@Ewoks: Mereka tidak memiliki ID pada penyimpanan internal. Itu hanya gambar, jika Anda perlu memuatnya ke banyak objek Gambar dan meneruskannya, Anda mungkin ingin memulai pertanyaan baru.
Hamid

Jawaban:

171

@EboMike: Saya tidak tahu itu Resources.getIdentifier()ada.

Dalam proyek saya, saya menggunakan kode berikut untuk melakukan itu:

public static int getResId(String resName, Class<?> c) {

    try {
        Field idField = c.getDeclaredField(resName);
        return idField.getInt(idField);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    } 
}

Ini akan digunakan seperti ini untuk mendapatkan nilai dari R.drawable.iconnilai integer sumber daya

int resID = getResId("icon", R.drawable.class); // or other resource class

Saya baru saja menemukan posting blog yang mengatakan bahwa Resources.getIdentifier()lebih lambat daripada menggunakan refleksi seperti yang saya lakukan. Lihat itu .

Makarse
sumber
8
@ Macarse: Saat ini, getIdentifier()harus melakukan dua pencarian refleksi. Dalam contoh Anda di atas, getIdentifier()akan menggunakan refleksi untuk mendapatkan Drawable.class, lalu pencarian refleksi lain untuk mendapatkan ID sumber daya. Itu akan menjelaskan perbedaan kecepatan. Yang sedang berkata, tidak ada yang terutama cepat dan karena itu benar-benar perlu di-cache (terutama jika digunakan dalam satu lingkaran, atau untuk baris dalam a ListView). Dan masalah besar pendekatan refleksi adalah bahwa ia membuat asumsi tentang internal Android yang mungkin berubah dalam beberapa rilis mendatang.
CommonsWare
1
@ CommonsWare: Benar. Saya sedang memeriksa bagaimana Android diterapkan dan akhirnya menjadi panggilan asli. gitorious.org/android-eeepc/base/blobs/… => gitorious.org/android-eeepc/base/blobs/…
Macarse
3
Saya akan menggunakan array integer dengan ID sebagai gantinya. Menggunakan string untuk ID tidak terdengar seperti pendekatan yang tepat.
EboMike
9
Mengapa contextparameternya?
Rudey
14
Memanggil harus getId ("ikon", R.drawable.class); tidak getResId ("ikon", konteks, Drawable.class);
Smeet
80

Anda dapat menggunakan fungsi ini untuk mendapatkan ID sumber daya.

public static int getResourceId(String pVariableName, String pResourcename, String pPackageName) 
{
    try {
        return getResources().getIdentifier(pVariableName, pResourcename, pPackageName);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    } 
}

Jadi jika Anda ingin mendapatkan fungsi panggilan drawable seperti ini

getResourceId("myIcon", "drawable", getPackageName());

dan untuk string Anda bisa menyebutnya seperti ini

getResourceId("myAppName", "string", getPackageName());

Baca ini

Azhar
sumber
11
Apa gunanya membuat fungsi yang hanya memanggil yang lain dan "menangani" kemungkinan pengecualian? Panggil getResources (). GetIdentifier () secara langsung.
Ricardo Meneghin Filho
37

Ini didasarkan pada jawaban @Macarse.

Gunakan ini untuk mendapatkan ID sumber daya dengan cara yang lebih cepat dan ramah kode.

public static int getId(String resourceName, Class<?> c) {
    try {
        Field idField = c.getDeclaredField(resourceName);
        return idField.getInt(idField);
    } catch (Exception e) {
        throw new RuntimeException("No resource ID found for: "
                + resourceName + " / " + c, e);
    }
}

Contoh:

getId("icon", R.drawable.class);
Daniel De León
sumber
30

Cara mendapatkan id sumber daya aplikasi dari nama sumber daya adalah pertanyaan yang cukup umum dan dijawab dengan baik.

Cara mendapatkan ID sumber daya Android asli dari nama sumber daya kurang dijawab dengan baik. Inilah solusi saya untuk mendapatkan sumber daya yang dapat ditarik Android berdasarkan nama sumber daya:

public static Drawable getAndroidDrawable(String pDrawableName){
    int resourceId=Resources.getSystem().getIdentifier(pDrawableName, "drawable", "android");
    if(resourceId==0){
        return null;
    } else {
        return Resources.getSystem().getDrawable(resourceId);
    }
}

Metode ini dapat dimodifikasi untuk mengakses jenis sumber daya lainnya.

Martin Pearman
sumber
sekarang .getResources (). getDrawable sudah tidak digunakan lagi if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){ return mContext.getDrawable(resourceId); } else { return mContext.getResources().getDrawable(resourceId); }
Evilripper
11

Jika Anda perlu memasangkan string dan int, lalu bagaimana dengan Peta?

static Map<String, Integer> icons = new HashMap<String, Integer>();

static {
    icons.add("icon1", R.drawable.icon);
    icons.add("icon2", R.drawable.othericon);
    icons.add("someicon", R.drawable.whatever);
}
Peter Knego
sumber
9

Anda dapat menggunakan Resources.getIdentifier(), meskipun Anda perlu menggunakan format untuk string Anda saat Anda menggunakannya dalam file XML Anda, yaitu package:drawable/icon.

EboMike
sumber
Jawaban saya di bawah adalah kebalikan dari ini. Masukkan id sumber daya, dan kemudian gunakan getResourceEntryName(id)untuk menemukan nama string. Tidak perlu mencari "ikon" dari teks yang lebih panjang.
Steve Waring
8

Saya memang suka ini, ini bekerja untuk saya:

    imageView.setImageResource(context.getResources().
         getIdentifier("drawable/apple", null, context.getPackageName()));
Sarvar Nishonboev
sumber
7
Simple method to get resource ID:

public int getDrawableName(Context ctx,String str){
    return ctx.getResources().getIdentifier(str,"drawable",ctx.getPackageName());
}
Ivan Vovk
sumber
1
Akan lebih baik jika Anda hanya memberikan beberapa informasi untuk jawaban Anda.
xMRi
6

Cara sederhana untuk mendapatkan ID sumber daya dari string. Di sini resourceName adalah nama sumber daya ImageView di folder drawable yang termasuk dalam file XML juga.

int resID = getResources().getIdentifier(resourceName, "id", getPackageName());
ImageView im = (ImageView) findViewById(resID);
Context context = im.getContext();
int id = context.getResources().getIdentifier(resourceName, "drawable",
context.getPackageName());
im.setImageResource(id);
Muhammad Adil
sumber
Terima kasih sobat itu sangat membantu .. Saya banyak mencari dan belum berhasil. Dengan melihat jawaban Anda, saya menemukan bahwa parameter kedua getIdentifierharus id. Ini bahkan tidak disebutkan di situs dev android. dari mana Anda mendapatkan informasi itu?
Prakash GPz
4

Karena Anda mengatakan Anda hanya ingin melewatkan satu parameter dan sepertinya tidak masalah, Anda bisa meneruskan pengidentifikasi sumber daya dan kemudian mencari nama string untuknya, dengan demikian:

String name = getResources().getResourceEntryName(id);

Ini mungkin cara paling efisien untuk mendapatkan kedua nilai tersebut. Anda tidak perlu dipusingkan untuk menemukan hanya bagian "ikon" dari string yang lebih panjang.

Steve Waring
sumber
2

Di res / tata letak / my_image_layout.xml Anda

<LinearLayout ...>
    <ImageView
        android:id="@+id/row_0_col_7"
      ...>
    </ImageView>
</LinearLayout>

Untuk mengambil ImageView itu dengan nilai id +,, di dalam kode java Anda, lakukan ini:

String row = "0";
String column= "7";
String tileID = "row_" + (row) + "_col_" + (column);
ImageView image = (ImageView) activity.findViewById(activity.getResources()
                .getIdentifier(tileID, "id", activity.getPackageName()));

/*Bottom code changes that ImageView to a different image. "blank" (R.mipmap.blank) is the name of an image I have in my drawable folder. */
image.setImageResource(R.mipmap.blank);  
Gene
sumber
2

Pendekatan Kotlin

inline fun <reified T: Class<R.drawable>> T.getId(resourceName: String): Int {
            return try {
                val idField = getDeclaredField (resourceName)
                idField.getInt(idField)
            } catch (e:Exception) {
                e.printStackTrace()
                -1
            }
        }

Pemakaian:

val resId = R.drawable::class.java.getId("icon")
Arsenius
sumber
1

Di MonoDroid / Xamarin.Android dapat Anda lakukan:

 var resourceId = Resources.GetIdentifier("icon", "drawable", PackageName);

Tetapi karena GetIdentifier tidak direkomendasikan di Android - Anda dapat menggunakan Reflection seperti ini:

 var resourceId = (int)typeof(Resource.Drawable).GetField("icon").GetValue(null);

di mana saya menyarankan untuk mencoba / menangkap atau memverifikasi string yang Anda lewati.

Daniele D.
sumber
1

Untuk mendapatkan id yang dapat ditarik dari nama sumber daya String saya menggunakan kode ini:

private int getResId(String resName) {
    int defId = -1;
    try {
        Field f = R.drawable.class.getDeclaredField(resName);
        Field def = R.drawable.class.getDeclaredField("transparent_flag");
        defId = def.getInt(null);
        return f.getInt(null);
    } catch (NoSuchFieldException | IllegalAccessException e) {
        return defId;
    }
}
bitvale
sumber