Android,从字符串中获取资源ID?
Posted
技术标签:
【中文标题】Android,从字符串中获取资源ID?【英文标题】:Android, getting resource ID from string? 【发布时间】:2011-05-24 13:53:29 【问题描述】:我需要将资源 ID 传递给我的一个类中的方法。它既需要使用引用指向的 id,也需要使用字符串。我应该如何最好地实现这一目标?
例如:
R.drawable.icon
我需要获取它的整数 ID,但我还需要访问字符串“icon”。
如果我必须传递给该方法的只是“图标”字符串,那就更好了。
【问题讨论】:
是否有可能以类似的方式获取保存到内部存储的文件的 ID?我有问题,因为我应该向我的画廊提供 ID 数组而不是位置(认为它是适配器).. 谢谢 @Ewoks:他们在内部存储上没有 ID。它们只是图像,如果您需要将它们加载到一堆 Image 对象中并传递它们,您可能想要开始一个新问题。 How to get a resource id with a known resource name? 的可能重复项 【参考方案1】:@EboMike:我不知道Resources.getIdentifier()
存在。
在我的项目中,我使用了以下代码:
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;
它会像这样用于获取R.drawable.icon
资源整数值的值
int resID = getResId("icon", R.drawable.class); // or other resource class
我刚刚发现一篇博文说Resources.getIdentifier()
比使用反射慢。 Check it out.
【讨论】:
@Macarse:目前,getIdentifier()
必须进行两次反射查找。在上面的示例中,getIdentifier()
将使用反射来获取 Drawable.class
,然后使用另一个反射查找来获取资源 ID。这将解释速度差异。话虽如此,两者都不是特别快,因此确实需要缓存(特别是如果在循环中使用,或者用于ListView
中的行)。反射方法的一个大问题是它对 android 的内部结构做出了假设,这些假设可能会在未来的某个版本中发生变化。
@CommonsWare:没错。我正在检查android是如何实现的,它最终是一个本地调用。 gitorious.org/android-eeepc/base/blobs/… => gitorious.org/android-eeepc/base/blobs/…
我会使用带有 ID 的整数数组。对 ID 使用字符串听起来不是正确的方法。
为什么要使用context
参数?
调用应该是getId("icon", R.drawable.class); not getResId("icon", context, Drawable.class);【参考方案2】:
你可以使用这个函数来获取资源ID。
public static int getResourceId(String pVariableName, String pResourcename, String pPackageName)
try
return getResources().getIdentifier(pVariableName, pResourcename, pPackageName);
catch (Exception e)
e.printStackTrace();
return -1;
所以如果你想获得 drawable 这样的调用函数
getResourceId("myIcon", "drawable", getPackageName());
对于字符串,你可以这样称呼它
getResourceId("myAppName", "string", getPackageName());
Read this
【讨论】:
创建一个简单地调用另一个函数并“处理”可能的异常的函数有什么意义?直接调用getResources().getIdentifier()。 赞成阐明如何传递类型以获取不同的种类或资源。 android dev 文档没有详细信息,并且先前答案中的“id”不适用于字符串。 是否也有相反的情况?从R.string.some_string
到“some_string”的含义?【参考方案3】:
这是基于@Macarse 的回答。
使用它以更快速和代码友好的方式获取资源 ID。
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);
例子:
getId("icon", R.drawable.class);
【讨论】:
【参考方案4】:如何从资源名称中获取 应用程序 资源 id 是一个非常常见且得到很好回答的问题。
如何从资源名称中获取 原生 Android 资源 id 的回答不太好。 这是我通过资源名称获取 Android 可绘制资源的解决方案:
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);
可以修改该方法以访问其他类型的资源。
【讨论】:
现在 .getResources().getDrawable 已弃用if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) return mContext.getDrawable(resourceId); else return mContext.getResources().getDrawable(resourceId);
【参考方案5】:
如果你需要配对一个字符串和一个int,那么Map呢?
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);
【讨论】:
【参考方案6】:我喜欢这样做,它对我有用:
imageView.setImageResource(context.getResources().
getIdentifier("drawable/apple", null, context.getPackageName()));
【讨论】:
谢谢。按预期工作。我使用了以下内容:view.context.resources.getIdentifier("drawable/item_car_$position", null, context.packageName)
.【参考方案7】:
Simple method to get resource ID:
public int getDrawableName(Context ctx,String str)
return ctx.getResources().getIdentifier(str,"drawable",ctx.getPackageName());
【讨论】:
如果您在答案中提供更多信息会更好。【参考方案8】:您可以使用Resources.getIdentifier()
,尽管您需要使用在 XML 文件中使用字符串的格式,即package:drawable/icon
。
【讨论】:
我在下面的回答与此相反。传入资源id,然后使用getResourceEntryName(id)
查找字符串名称。从较长的文本中找到“图标”并不麻烦。【参考方案9】:
既然你说你只想传递一个参数,而且似乎并不重要,你可以传入资源标识符,然后找出它的字符串名称,因此:
String name = getResources().getResourceEntryName(id);
这可能是获取这两个值的最有效方式。您不必在较长的字符串中只找到“图标”部分。
【讨论】:
【参考方案10】:从字符串中获取资源 ID 的简单方法。 这里 resourceName 是可绘制文件夹中资源 ImageView 的名称,该文件夹也包含在 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);
【讨论】:
谢谢,这真的很有帮助。我搜索了很多,但没有得到它的工作。通过看到你的回答,我发现getIdentifier
的第二个参数必须是id
。这在 android 开发网站中甚至都没有提到。你从哪里得到这些信息的?【参考方案11】:
Kotlin 方法
inline fun <reified T: Class<*>> T.getId(resourceName: String): Int
return try
val idField = getDeclaredField (resourceName)
idField.getInt(idField)
catch (e:Exception)
e.printStackTrace()
-1
用法:
val resId = R.drawable::class.java.getId("icon")
或者:
val resId = R.id::class.java.getId("viewId")
【讨论】:
这行得通,但它到底在做什么?它有一个非常奇怪的语法。它的性能如何?【参考方案12】:在您的 res/layout/my_image_layout.xml 中
<LinearLayout ...>
<ImageView
android:id="@+id/row_0_col_7"
...>
</ImageView>
</LinearLayout>
要通过 @+id 值获取 ImageView,请在您的 java 代码中执行以下操作:
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);
【讨论】:
【参考方案13】:在 MonoDroid / Xamarin.Android 中你可以这样做:
var resourceId = Resources.GetIdentifier("icon", "drawable", PackageName);
但由于在 Android 中不推荐使用 GetIdentifier - 您可以像这样使用反射:
var resourceId = (int)typeof(Resource.Drawable).GetField("icon").GetValue(null);
我建议在其中放置一个 try/catch 或验证您传递的字符串。
【讨论】:
【参考方案14】:为了从 String 资源名称获取 Drawable id,我使用以下代码:
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;
【讨论】:
以上是关于Android,从字符串中获取资源ID?的主要内容,如果未能解决你的问题,请参考以下文章
Android 用字符串资源名称获取int型资源id的几种方式
Android:android.content.res.Resources$NotFoundException:字符串资源 ID #0x5
android.content.res.Resources$NotFoundException: Main 中的字符串资源 ID 致命异常