场景
BaseActivity放在library中,所有页面都有一个返回按钮,id为id_iv_back。想在BaseActivity统一设置返回点击事件。但是library无法获取app的R文件,也就无法获取该引用资源。。。
解决方法
所以我们必须实时的获取这个十六进制的数值。有两个方式可以选择:
1.(推荐)通过android.content.res.Resources类的
int getIdentifier(String name, String defType, String defPackage)
. 比如,我们需要在Activity中设置布局,我们要得到res/layout/目录下的 “main_layout.xml” 布局文件的ID.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
int id = getResources().getIdentifier(“main_layout“, "layout", getPackageName());
setContentView(id);
...
}
2.使用Java语言的反射机制。但是使用反射毕竟麻烦。
Field field = R.layout.class.getField("main_layout");
int i = field.getInt(new R.layout());
return i;
封装:
阅读腾讯TIM的demo代码时候发现了该封装方法。
/**
* 根据资源的名字获取其ID值
* */
public class MResource {
public static int getIdByName(Context context, String className, String name) {
String packageName = context.getPackageName();
Class r = null;
int id = 0;
try {
r = Class.forName(packageName + ".R");
Class[] classes = r.getClasses();
Class desireClass = null;
for (int i = 0; i < classes.length; ++i) {
if (classes[i].getName().split("\\$")[1].equals(className)) {
desireClass = classes[i];
break;
}
}
if (desireClass != null) {
id = desireClass.getField(name).getInt(desireClass);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return id;
}
public static int[] getIdsByName(Context context, String className, String name) {
String packageName = context.getPackageName();
Class r = null;
int[] ids = null;
try {
r = Class.forName(packageName + ".R");
Class[] classes = r.getClasses();
Class desireClass = null;
for (int i = 0; i < classes.length; ++i) {
if (classes[i].getName().split("\\$")[1].equals(className)) {
desireClass = classes[i];
break;
}
}
if ((desireClass != null) && (desireClass.getField(name).get(desireClass)) != null && (desireClass.getField(name).get(desireClass).getClass().isArray())) {
ids = (int[]) desireClass.getField(name).get(desireClass);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return ids;
}
}
在BaseActivity中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResID());
if (null != findViewById(MResource.getIdByName(getApplication(), "id", "id_iv_back"))) {
findViewById(MResource.getIdByName(getApplication(), "id", "id_iv_back")).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}