一般情况下我们都是直接使用资源 Id 来获取资源的,简单而又方便.
例如:
imageView.setImageResource(R.drawable.ic_launcher_background)
但是有些情况下,这种方式就显的有点复杂了.
例如这么一种情况 :
要根据 type 的值来选择对应的图片.
type : 取值范围是0…9
对应的图片为: iconvip0, iconvip1 …. iconvip9.
这时候如果用资源 id 的方式来取图片的话,代码是这样的:
switch (type){
case 0:
imageView.setImageResource(R.drawable.iconvip0);
break;
case 1:
imageView.setImageResource(R.drawable.iconvip1);
break;
case 2:
imageView.setImageResource(R.drawable.iconvip2);
break;
case 3:
imageView.setImageResource(R.drawable.iconvip3);
break;
case 4:
imageView.setImageResource(R.drawable.iconvip4);
break;
case 5:
imageView.setImageResource(R.drawable.iconvip5);
break;
case 6:
imageView.setImageResource(R.drawable.iconvip6);
break;
case 7:
imageView.setImageResource(R.drawable.iconvip7);
break;
case 8:
imageView.setImageResource(R.drawable.iconvip8);
break;
case 9:
imageView.setImageResource(R.drawable.iconvip9);
break;
}
看到这样的代码,虽然代码很简单,也是有点头大的.何况这才10个,若是100个呢,1000个呢不敢想象…
解决方法
一行代码直接搞定:
imageView.setImageResource(getResources().getIdentifier("iconvip"+type,"drawable",getPackageName()));
其实就是 Resources 的一个方法 getIdentifier(String name, String defType, String defPackage)
第一个参数 name : 就是资源名
第二个参数 defType : 就是资源所存在的文件夹
第三个参数 defPackage : 就是程序的包名
还有另一种写法:
imageView.setImageResource(getResources().getIdentifier(packageName + ":drawable/iconvip"+type, null, null);
同样的我们还可以利用它来获取一些尺寸信息,如状态栏的高度
int resourceId = this.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
int statusBarHeight = this.getResources().getDimensionPixelSize(resourceId);
}
源码部分
好奇的话,我们跟踪源码看看.
// Resources 类
public int getIdentifier(String name, String defType, String defPackage) {
return mResourcesImpl.getIdentifier(name, defType, defPackage);
}
又调用了 ResourcesImpl类,跟进去看看吧.
// ResourcesImpl类
int getIdentifier(String name, String defType, String defPackage) {
if (name == null) {
throw new NullPointerException("name is null");
}
try {
return Integer.parseInt(name);
} catch (Exception e) {
// Ignore
}
return mAssets.getResourceIdentifier(name, defType, defPackage);
}
可以看到最后其实是调用了mAssets
的 getResourceIdentifier
方法
mAssets
其实是AssetManager
我们再看看AssetManager
里面
native final int getResourceIdentifier(String name,
String defType,
String defPackage);
到这里看到实际上是一个 native 方法.
总结getIdentifier
这个方法在某些的特定的情况下能给我们提供便利,但是还是尽量的少使用它,因为在有资源 id 的时候,使用资源 id来获取资源,效率会更高.