有过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无法使用android:onClick属性相关推荐

  1. Android解决fragment来回切换重新实例化问题

    1. 关于Android studio新建的Bottom Navigation Activity 2. 解决思路 3. 具体操作 4. 关于androidstudio自生成的xml文件的代码修改 1. ...

  2. android viewpager fragment传值,Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题...

    前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapt ...

  3. android没有adm_解决AMD无法使用Android studio问题

    前提:你的电脑是AMD处理器,想使用Android studio,自己的电脑系统是win10家庭版,在百度找到勾选hyper-v就能用,然后发现在自己的电脑上面找不到,又要去BIOS界面里面更改配置发 ...

  4. required android.app.fragment,required:'android.app.Fragment'

    郑州app开发过程中遇到required:'android.app.Fragment'.这个问题主要是android版本问题. 这句话只老版本的 //FragmentManager manager = ...

  5. amd用不了android studio,解决AMD无法使用Android studio问题

    前提:你的电脑是AMD处理器,想使用Android studio,自己的电脑系统是win10家庭版,在百度找到勾选hyper-v就能用,然后发现在自己的电脑上面找不到,又要去BIOS界面里面更改配置发 ...

  6. android 判断fragment类型,Android 判断当前Fragment是否可见(Visible)

    判断当前Fragment是否可见 public abstract class BaseFragment extends Fragment { /** Fragment当前状态是否可见*/ protec ...

  7. Android 进阶 Fragment 介绍和使用 (一)

    Fragment概述 Fragment是activity的界面中的一部分或一种行为.你可以把多个Fragment们组合到一个activity中来创建一个多面界面并且你可以在多个activity中重用一 ...

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

    转载出处:http://blog.csdn.net/lmj623565791/article/details/37970961 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragme ...

  9. Android之Fragment(一)

    Fragment的产生与介绍 Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视.针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以适应平板 ...

最新文章

  1. matlab axis
  2. .pyc文件还原.py文件_从镜像文件还原分区 (系统还原)
  3. 判断闰年 及其某天为这一年的多少天
  4. C语言解释器的实现--存储结构(一)
  5. 关于GC.Collect在不同机器上表现不一致问题
  6. 想要导航提示页最新安卓区_最新微信小程序授权的详细处理思路(一)
  7. python中定义变量为啥要用下划线_关于python中带下划线的变量和函数 的意义
  8. mongodb副本集搭建
  9. 2021 年 RISC-V 会有什么大变化?
  10. 华为云新春送福,大吉大利今晚红包雨!
  11. 两种方式打开jar文件
  12. linux安装智能输入法,Ubuntu中文智能拼音输入法配置
  13. Java实现经纬度格式转化
  14. 种类并查集(POJ1703)
  15. 计算机网络设备调试员报名,工信部网络设备调试员一级高级技师、二级技师
  16. ASEMI代理ST/意法STW78N65M5原厂渠道汽车级MOSFET
  17. Linux安装回收站trash-cli
  18. 汇编文件大写.S后缀和小写.s后缀的区别
  19. 一种排序--引发:java两个引用指向同一个对象
  20. addonsmaker怎么制作_addons制作器 v1.14.3 苹果IOS版

热门文章

  1. android改变下拉框字体颜色,有没有简单的方法来改变Android中的Spinner下拉颜色?...
  2. 寄存器分配图着色_【02】从零开始的卡通渲染-着色篇1
  3. ss流量查询 php,Linux_Linux怎么使用ss命令查看系统的socket状态,  Linux系统中,ss命令可用于 - phpStudy...
  4. 小学毕业java_Java运算符
  5. 你常吃的便利食品,正在加速你的衰老……研究发现饮食与DNA损伤有关
  6. java面试 泛型_Java面试题五:Java 的泛型, super T 和 extends T 的区别
  7. 如何在data visualization 中update svg_如何操作小程序页面中data数据区中的数据
  8. 怎么用python进行回归预测_使用Python训练回归模型并进行预测
  9. linux 守护进程_网络工程师之linux守护进程
  10. oracle rollup分组没有数据时为0_Hive 入门数据分析基础 5