Pre-Honeycomb(Android 3),每个Activity都已注册,可通过Layout的XML中的 onClick
标记处理按钮点击:
android:onClick="myClickMethod"
在该方法中,您可以使用 view.getId()
和switch语句来执行按钮逻辑 .
随着Honeycomb的推出,我将这些活动分解为碎片,可以在许多不同的活动中重复使用 . 按钮的大多数行为都是与Activity无关的,我希望代码驻留在Fragments文件中,而不使用为每个按钮注册 OnClickListener
的旧(pre 1.6)方法 .
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
问题是,当我的布局被夸大时,它仍然是接收按钮点击的托管活动,而不是单个碎片 . 对两者都有好的方法
-
注册片段以接收按钮点击?
-
将活动中的点击事件传递给他们所属的片段?
17 回答
如果您使用android:Onclick =“”在xml中注册,则回调将被提供给您的片段所属的上下文中受尊重的Activity(getActivity()) . 如果在Activity中找不到这样的方法,那么系统将抛出异常 .
最佳解决方案IMHO:
在片段中:
然后在Fragment的onViewStateRestored中:
我认为问题是视图仍然是活动,而不是片段 . 片段没有自己的任何独立视图,并附加到父活动视图 . 这就是为什么事件最终在Activity中,而不是片段 . 不幸的是,但我认为你需要一些代码来完成这项工作 .
我在转换过程中一直在做的只是添加一个调用旧事件处理程序的单击侦听器 .
例如:
您的活动正在接收必须使用的回调:
如果您希望片段接收回调,请执行以下操作:
并在Fragment上实现
onClickListener
接口您可能需要考虑将EventBus用于解耦事件 . 您可以非常轻松地监听事件 . 您还可以确保在ui线程上接收事件(而不是为每个事件订阅调用runOnUiThread ..)
https://github.com/greenrobot/EventBus
来自Github:
你可以这样做:
活动:
分段:
回应@Ameen谁想要更少的耦合,所以片段是可重复使用的
接口:
活动:
分段:
在我的用例中,我有50个奇怪的ImageViews,我需要挂钩到一个onClick方法 . 我的解决方案是遍历片段内的视图并在每个视图上设置相同的onclick侦听器:
加入Blundell的回答,
如果你有更多的片段,有大量的onClicks:
活动:
在你的片段中:
这一直对我有用:( Android工作室)
这是另一种方式:
1.像这样创建一个BaseFragment:
2.使用
代替
3.在你的活动中:
和
希望能帮助到你 .
当我看到答案时,他们有点老了 . 最近谷歌推出了DataBinding,这更容易处理 onClick 或在你的xml中分配 .
这是一个很好的例子,你可以看到如何处理这个:
还有关于DataBinding的非常好的教程,你可以找到它Here .
我最近解决了这个问题,无需向上下文Activity添加方法或必须实现OnClickListener . 我不确定它是否是一个“有效”的解决方案,但它确实有效 .
基于:https://developer.android.com/tools/data-binding/guide.html#binding_events
它可以通过数据绑定来完成:只需将您的片段实例添加为变量,然后您可以使用onClick链接任何方法 .
片段链接代码将是......
在使用片段时,我宁愿在代码中使用单击处理而不是在XML中使用
onClick
属性 .将活动迁移到片段时,这变得更加容易 . 您可以直接从每个
case
块调用单击处理程序(以前在XML中设置为android:onClick
) .在处理片段中的点击时,这对我来说比
android:onClick
更简单 .我更喜欢使用以下解决方案来处理onClick事件 . 这适用于Activity和Fragments .
您可以将回调定义为XML布局的属性 . 文章Custom XML Attributes For Your Custom Android Widgets将向您展示如何为自定义小部件执行此操作 . 归功于Kevin Dion :)
我正在调查是否可以向基础Fragment类添加可样式属性 .
基本思想是在处理onClick回调时具有View实现的相同功能 .
ButterKnife可能是解决杂乱问题的最佳解决方案 . 它使用注释处理器生成所谓的"old method"样板代码 .
但是仍然可以使用onClick方法,使用自定义充气器 .
如何使用
实施
我'd like to add to Adjorn Linkz' s answer .
如果您需要多个处理程序,则可以使用lambda引用
这里的诀窍是
handler
方法的签名匹配View.OnClickListener.onClick
签名 . 这样,您将不需要View.OnClickListener
接口 .此外,您不需要任何switch语句 .
遗憾的是,此方法仅限于需要单个方法或lambda的接口 .