[Android]Fragment无法使用android:onClick属性
来源:互联网 发布:创建my-js.js文件 编辑:程序博客网 时间:2024/05/26 16:00
来源:http://blog.163.com/lvan100@yeah/blog/static/68117214201502110012437/
有过MFC或者WinForm或者WPF经验的程序员一定对于Button的Click事件绑定情有独钟,然而当转移到Android平台开发的时候会发现,之前的种种便利全都不在,只有看着闹心的setOnClickListener()。
实际上Android里面也有同样的功能,在布局文件中同样可以给Button绑定Click时间的响应函数。如:
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="OnClick"
android:text="Button" />
然后在Activity里面实现OnClick()函数:
public void OnClick(View v) {
System.out.println("Click");
}
真的很方便,不是吗?但是你千万不要高兴的太早,因为正有一个很大的坑在等着你!不信你瞧着。
Android中有很多很多的布局器,它们带来了极大的灵活性。与此同时,也出现了一种叫做Fragment的东西——它不是布局器,却可以管理布局器。Fragment为开发灵活的界面组件库提供了可能,同样的我们也想到在Fragment管理的布局文件中使用按钮的onClick属性。多么自然!
问题就出在Fragment身上,前面说了它不是布局器,所以它不具备渲染视图的能力,它管理的布局器最终要加载到一个ViewGroup对象内,由ViewGroup对象来渲染。而视图树并不知道每一个子控件来源于哪里,这就导致了一个结果:不管是在什么地方定义的onClick属性,都必须在包含该Button的Activity中去寻找OnClick()方法。
可能有人说,API中对onClick早有说明:设置点击时从上下文中调用指定的方法,只是你不知道而已。事实确实是这样,但是我是一个追根溯源的人,如果我没有遇到这么多的问题,我可能只知道应该怎么做,却不知道为何应该这样做。
抛开onClick属性,我们仍然可以使用代码的方式实现对Click的事件响应,但是毕竟——不优雅——了。
曾经我想到了一种办法——使用约定:让使用该Fragment的Activity实现一个包含所有OnClick()函数的接口。但是那样做仍然不够优雅!
对于Java程序员来说,反射有时候是一种水到渠成的方案。下面的ParseButtonIdClick()函数就是从配置文件中读取指定id的Button的OnClick实现函数,然后使用setOnClickListener()将实现函数和Button的Click事件进行绑定。
/**
* 解析按钮的Click事件响应
*/
protected void ParseButtonIdClick() {
XmlResourceParser xmlParser = rootView.getResources().getXml(
R.xml.button_id_click);
int event = XmlPullParser.START_DOCUMENT;
try {
event = xmlParser.getEventType();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
String pkgName = (new Throwable()).getStackTrace()[0].getClassName();
System.out.println(pkgName);
do {
switch (event) {
case XmlPullParser.START_TAG: {
if (xmlParser.getName().equals("Button")) {
String id_str = xmlParser.getAttributeValue(0);
String click = xmlParser.getAttributeValue(1);
try {
Class<?> classRId = Class
.forName("com.abc.keyboard.R$id");
Field filedId = classRId.getField(id_str);
int id_int = filedId.getInt(null);
Button idButton = (Button) rootView
.findViewById(id_int);
final Method method = getClass().getDeclaredMethod(
click, View.class);
idButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
method.invoke(KeyboardFragmentBase.this, v);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
break;
}
try {
event = xmlParser.next();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} while (event != XmlPullParser.END_DOCUMENT);
xmlParser.close();
}
- [Android]Fragment无法使用android:onClick属性
- [Android]解决Fragment无法使用android:onClick属性
- Android之使用Fragment无法相应onClick事件
- android:onClick属性使用之ToggleButton
- android:onClick属性详解
- android:onClick属性
- Android:onClick属性
- Xamarin.Android中使用android:onClick="xxx"属性
- android:onClick 属性的应用
- android:onClick 属性的应用
- Android:onClick 底层属性调用
- Android布局中onClick属性
- Android使用TextView,设置onClick属性无效解决办法
- xml中使用android:onClick
- Android Button 添加 onclick 属性的注意事项
- Android 5.0使用android:onClick属性出现崩溃的原因及解决方案
- android:onClick
- Android onClick
- java类加载机制
- centos linux 安装PHP+APACE +MYSQL
- Eclipse安装反编译工具查看Jar包源码
- 安装和运行assets目录下的Apk
- Python 数据结构与算法——deque
- [Android]Fragment无法使用android:onClick属性
- Android学习之自定义TextWatcher来监听文本最大输入字数
- SQL 内/外连接 示意图
- Android APK反编译详解(附图)
- 最新版SDWebImage的使用
- ReactiveCocoa 2
- 如何不让存在EditText界面在打开时不自动弹出软键盘
- 第一篇博客
- eclipse 改变workspace及jsp文件的默认编码格式