[Android]解决Fragment无法使用android:onClick属性

转载 2015年07月09日 16:22:55

有过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();
}

我不是一个Java高手,所以如果有人能优化上面的代码,我会十分高兴。

相关文章推荐

Android:在Fragment中,onClick失效的解决方法

平时习惯写onclic方法, 但是有时候不是在Activity中,比如:Fragment中用onclick无效, 只能用 id 跳转或者弹框: 比如按钮 Button 或者 Lineayout ...
  • ssh159
  • ssh159
  • 2017-03-22 15:47
  • 1175

[Android]Fragment无法使用android:onClick属性

来源:http://blog.163.com/lvan100@yeah/blog/static/68117214201502110012437/ 有过MFC或者WinForm或者WPF经验的...

fragment中设置点击事件(onclick)使用intent进行通信

今天在学习安卓的过程中,需要实现一个功能通信,就是需要在一个fragment中设置一个按钮,点击之后会跳转到一个新的页面,我首先想到是给按钮设置一个onclick属性, 按照以往写了这样的代码 pu...

Android Fragment完全解析,关于碎片你所需知道的一切

我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了,我相信大家都已经非常熟悉了,这里就不再赘述。 但是Activity也有它的局限性,同样的界面在手机...

Fragment从入门到精通之Activity中响应Fragment中的事件③

在Activity中响应Fragment中的事件当我们想要在fragment去执行一些代码,但是这个代码我们想要把它放在activity里面去执行。那么activity里这段代码是如何在fragmen...

Android 属性动画(Property Animation) 完全解析 (下)

上一篇Android 属性动画(Property Animation) 完全解析 (上)已经基本展示了属性动画的核心用法:ObjectAnimator实现动画,ValueAnimator实现动画,An...

Android Fragment 真正的完全解析(上)

自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragment如何产...

Android中如何为Fragment中的按钮添加监听事件

如何为每个Fragment中的按钮等元素添加监听事件

在Fragment中进行button setonclicklistener的问题

今天项目过程中发现了一些问题,自己本身没有系统的学习过android,就是想到什么做什么的。 今天在用 fragment(碎片)按钮点击的时候碰到了问题。 自己是依...

Android中Fragment点击事件的添加(及点击事件无响应的原因)

这两天刚开始用fragment,在写点击事件的时候出现了点击事件无响应的问题。 接下来举一个例子说明fragment中点击事件的基本写法。 这个小程序由一个activity嵌套一个fragm...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)