Android项目,library中根据资源id获取资源
2016-03-18 14:09
531 查看
场景
BaseActivity放在library中,所有页面都有一个返回按钮,id为id_iv_back。想在BaseActivity统一设置返回点击事件。但是library无法获取app的R文件,也就无法获取该引用资源。。。
解决方法
所以我们必须实时的获取这个十六进制的数值。有两个方式可以选择:
1.(推荐)通过android.content.res.Resources类的
2.使用Java语言的反射机制。但是使用反射毕竟麻烦。
封装:
阅读腾讯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();
}
});
}
}
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();
}
});
}
}
相关文章推荐
- I.MX6 android 禁止低电量自动关机
- rk3288 编写Android.mk 形式内置APK
- Android自定义控件——FloatLayout
- android系统简介
- Android 通知栏Notification的整合 全面学习
- Android Download 下载功能深入研究(四) : 系统应用DownloadProvider的改进
- Android四大组件之---activity生命周期详解
- Android 快速开发框架:推荐10个框架:afinal、ThinkAndroid、andBase、KJFrameForAndroid、SmartAndroid、dhroid..
- android ListView嵌入EditText焦点和值错误问题
- android 一些基础用法
- Android项目:手机安全卫士(14)—— 短信备份
- android给EditText加金额的属性,带元,角和分,如¥12.34
- Android逆向分析基础-反破解技术
- context和context和android的关联
- android开发——跨进程通讯数据传递(三)
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- jboss和.net和android的关联
- Android二级分类列表ListView GirdView in ViewPager
- Android MediaPlayer视频播放详情
- 在低版本android系统上实现Material design应用(转载)