~~~~我的生活,我的点点滴滴!!
前几天学习疯狂android时,最后有一个连连看例子,由于半路出家的,不会java,走马观花的看完前面的一些基本知识,希望通过一两个例子的
解决来快速学习android,发现里面有一个利用 反射 来找到对应的图像这个很巧妙、很有意思。下面特此记录下来。
场景:
当我们在drawable文件夹下添加一个图片XX时,R文件中的类drawable中也会自动添加一个常量值R.drawable.XX。我习惯称R.drawable.XX为宏名。
问题:
我们怎么动态的获得到图像,而不用更改一行代码了?我们知道所有在res下面的文件,都会自动在gen下的一个叫R.java里面生成一个唯一的16进制的编
号,我们可以利用这个来找到我们需要的图像文件
解决:
利用 反射 机制就可以完美的解决这个问题,看下面代码:
import java.lang.reflect.Field;//反射用到的类
import com.jelly.waimai.R;//我的工程的R文件
public class GetPic {
public static int getPic(String pid) {
Field f;
try {
f = R.drawable.class.getField(pid);
return f.getInt(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return 0;
}
}
上面代码刨去捕获的异常,剩下的干货其实并不多
Field f;
f = R.drawable.class.getField(pid);
return f.getInt(null);
Filed类表示的就是类中的成员变量,成员变量本身就有另一个叫法“域”(Filed)。每一个类都有这么一个方法getField。声明如下: public Field getField(String name)。 这个是属于Class类型的方法,java中每一个类都有一个对应的Class类型的对象(Class本身也是一种类)不
能直接R.drawable.getField(pid)。需要R.drawable.class.getField(pid)。明白了吗?.class的目的就是获得R.drawable类的Class对象。 因为R文件中
是以整数的方式来表示(索引)资源的。所以我们执行f.getInt(null);方法声明如下: public int getInt (Object object)这个方法在当 f 是static
类型的时候,是会忽略参数object的,所以传递null就可以了。否则如果drawable类不是static类型的,这里是需要传递一个drawable对象的。 当我们
debug或打印其值时,可能发觉和R.java里面不一样,那是因为一个是16进制,一个是10进制。
下面是连连中代码:
public static List<Integer> getImageValues()
{
try {
// 资源反射
// Filed类表示的就是类中的成员变量,成员变量本身就有另一个叫法“域”(Filed)
Field[] drawFields = R.drawable.class.getFields();
List<Integer> resourceValuesIntegers = new ArrayList<Integer>();
for( Field field : drawFields )
{
if( field.getName().indexOf("p_") != -1 )
{
resourceValuesIntegers.add(field.getInt(R.drawable.class));
}
}
return resourceValuesIntegers;
} catch (Exception e) {
// TODO: handle exception
Log.e("ImageUtil", e.getMessage().toString());
return null;
}
}
这里使用的getFields(),道理一样的。正如上面所说,我们最好还是封装一个专门的类来处理这个 反射 这样看起来也专业,哈哈~~~~~~