Android, nhận ID tài nguyên từ chuỗi?


158

Tôi cần truyền ID tài nguyên cho một phương thức trong một trong các lớp của mình. Nó cần sử dụng cả id mà tham chiếu trỏ tới và nó cũng cần chuỗi. Làm thế nào tốt nhất tôi nên đạt được điều này?

Ví dụ:

R.drawable.icon

Tôi cần lấy ID số nguyên này, nhưng tôi cũng cần truy cập vào chuỗi "biểu tượng".

Sẽ tốt hơn nếu tất cả những gì tôi phải truyền cho phương thức là chuỗi "biểu tượng".


Có thể theo cách tương tự với getId của các tệp được lưu vào bộ nhớ trong không? Tôi có vấn đề vì tôi nên cung cấp mảng id thay vì vị trí cho thư viện của mình (nghĩ đó là bộ chuyển đổi) .. cảm ơn
Ewoks

@Ewoks: Họ không có ID trên bộ nhớ trong. Chúng chỉ là hình ảnh, nếu bất cứ điều gì bạn cần để tải chúng vào một loạt các đối tượng Hình ảnh và vượt qua chúng, bạn có thể muốn bắt đầu một câu hỏi mới.
Hamid

Câu trả lời:


171

@EboMike: Tôi không biết điều đó Resources.getIdentifier()đã tồn tại.

Trong các dự án của tôi, tôi đã sử dụng mã sau đây để làm điều đó:

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

Nó sẽ được sử dụng như thế này để lấy giá trị của giá trị R.drawable.iconnguyên tài nguyên

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

Tôi chỉ tìm thấy một bài viết trên blog nói rằng Resources.getIdentifier()nó chậm hơn so với việc sử dụng sự phản chiếu như tôi đã làm. Kiểm tra nó ra .


8
@Macude: Hiện tại, getIdentifier()phải thực hiện hai tra cứu phản ánh. Trong ví dụ của bạn ở trên, getIdentifier()sẽ sử dụng sự phản chiếu để có được Drawable.class, sau đó tìm kiếm sự phản chiếu khác để lấy ID tài nguyên. Điều đó sẽ chiếm sự khác biệt về tốc độ. Điều đó đang được nói, không phải là đặc biệt nhanh chóng và do đó thực sự cần phải được lưu trữ (đặc biệt nếu được sử dụng trong một vòng lặp, hoặc cho các hàng trong một ListView). Và vấn đề lớn của phương pháp phản ánh là nó đưa ra các giả định về các phần bên trong của Android có thể thay đổi trong một số bản phát hành trong tương lai.
CommonsWare

1
@CommonsWare: Đúng vậy. Tôi đã kiểm tra cách Android triển khai và kết thúc là một cuộc gọi riêng. gitorious.org/android-eeepc/base/blobs/ Lần => gitorious.org/android-eeepc/base/blobs/ Lỗi
Macude

3
Tôi sẽ sử dụng một mảng số nguyên với ID thay thế. Sử dụng chuỗi cho ID không giống như cách tiếp cận đúng.
EboMike

9
Tại sao contexttham số?
Rudey

14
Gọi nên là getId ("icon", R.drawable. Class); không getResId ("icon", bối cảnh, Drawable. class);
Smeet

80

Bạn có thể sử dụng chức năng này để lấy ID tài nguyên.

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

Vì vậy, nếu bạn muốn nhận được cho drawable chức năng cuộc gọi như thế này

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

và đối với chuỗi bạn có thể gọi nó như thế này

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

Đọc này


11
Điểm làm cho một chức năng chỉ đơn giản gọi một chức năng khác và "xử lý" một ngoại lệ có thể là gì? Gọi trực tiếp getResource (). GetIdentifier ().
Ricardo Meneghin Filho

37

Điều này dựa trên câu trả lời @Macude.

Sử dụng công cụ này để lấy Id tài nguyên theo cách nhanh hơn và mã thân thiện hơn.

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

Thí dụ:

getId("icon", R.drawable.class);

30

Làm thế nào để có được một id tài nguyên ứng dụng từ tên tài nguyên là một câu hỏi khá phổ biến và được trả lời tốt.

Cách nhận id tài nguyên Android gốc từ tên tài nguyên ít được trả lời. Đây là giải pháp của tôi để có được tài nguyên có thể rút được của Android theo tên tài nguyên:

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

Phương pháp có thể được sửa đổi để truy cập các loại tài nguyên khác.


ngay bây giờ .getResource (). getDrawable bị phản đối 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

Nếu bạn cần ghép một chuỗi và một int, vậy còn Bản đồ thì sao?

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

9

Bạn có thể sử dụng Resources.getIdentifier(), mặc dù bạn cần sử dụng định dạng cho chuỗi của mình khi bạn sử dụng nó trong các tệp XML của mình package:drawable/icon.


Câu trả lời của tôi dưới đây là mặt trái của điều này. Truyền vào id tài nguyên, và sau đó sử dụng getResourceEntryName(id)để tìm tên chuỗi. Không có lộn xộn để tìm "biểu tượng" từ văn bản dài hơn.
Steve Waring

8

Tôi đã làm như thế này, nó đang làm việc cho tôi:

    imageView.setImageResource(context.getResources().
         getIdentifier("drawable/apple", null, context.getPackageName()));

7
Simple method to get resource ID:

public int getDrawableName(Context ctx,String str){
    return ctx.getResources().getIdentifier(str,"drawable",ctx.getPackageName());
}

1
Sẽ tốt hơn nếu bạn chỉ cung cấp thêm một số thông tin cho câu trả lời của bạn.
xMRi

6

Một cách đơn giản để lấy ID tài nguyên từ chuỗi. Ở đây resourceName là tên của ImageView tài nguyên trong thư mục drawable cũng được bao gồm trong tệp XML.

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

Cảm ơn người đàn ông nó thực sự hữu ích .. Tôi đã tìm kiếm rất nhiều và nó đã không làm việc. Bằng cách xem câu trả lời của bạn, tôi thấy rằng tham số thứ hai getIdentifierphải có id. Điều này thậm chí không được đề cập trong trang web dev android. bạn lấy thông tin đó ở đâu?
Prakash GPz 20/03/2016

4

Vì bạn nói rằng bạn chỉ muốn truyền một tham số và dường như không có vấn đề gì, nên bạn có thể chuyển định danh tài nguyên vào và sau đó tìm ra tên chuỗi cho nó, do đó:

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

Đây có thể là cách hiệu quả nhất để có được cả hai giá trị. Bạn không phải loay hoay tìm kiếm phần "biểu tượng" từ một chuỗi dài hơn.


2

Trong res / layout / my_image_layout.xml của bạn

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

Để lấy ImageView đó bằng giá trị @ + id của nó, bên trong mã java của bạn làm điều này:

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

2

Cách tiếp cận của 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
            }
        }

Sử dụng:

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

1

Trong MonoDroid / Xamarin.Android bạn có thể làm:

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

Nhưng vì GetIdentifier không được khuyến nghị trong Android - bạn có thể sử dụng Reflection như thế này:

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

nơi tôi đề nghị đặt thử / bắt hoặc xác minh chuỗi bạn đang đi qua.


1

Để nhận id Drawable từ tên tài nguyên chuỗi Tôi đang sử dụng mã này:

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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.