EventBus框架在Android多Pane(Fragment)中的使用实例

通常多pane的设计中,比如Fragment A是个Headline,Fragement B是detail,那么B通常需要实现A的点击事件的接口,这样子的话,两个fragment就高耦合了,而且需要在Fragment A中编写一个interface,如果Fragment很多,情景更复杂些,就乱了。

这里可以使用EventBus这个框架,一个典型的发布者-订阅者模式。具体可以参考:

https://github.com/greenrobot/EventBus

使用方法大致如下:

这个例子来源于Android Developers的一个典型的多Fragment的例子,左边Fragment是HeadlineFragment,含有很多标题的listview,右边是DetailFragment,点击左边Fragment中一项会刷新右边的Fragment。

EventBus框架在Android多Pane(Fragment)中的使用实例

a. 首先定义自己的Event,这里其实是随便写个类,例子中Headline需传一个点击时候的listview的position给Detail fragment,所以可以写个包装int类型的MessageEvent:

public class MessageEvent {

    public int position;

    public MessageEvent(int position) {
        this.position = position;
    }
}

b.  在订阅者(即Detail fragment或者说fragment B)中,onstart和onstop要注册/解注册:

//DetailFragment.java

@Override
public void onStart() {
    super.onStart();;
    EventBus.getDefault().register(this);
}

@Override
public void onStart() {
    super.onStart();
    setNewsCategory(0);
    EventBus.getDefault().register(this);
}

c. 在订阅者(即Detail fragment或者说fragment B)中,写一个名字叫onEvent的函数,带回来的参数是MessageEvent类型,这个函数即被调用的方法,等待Headline传过来包装了position数据的MessageEvent对象

//DetailFragment.java
public void onEvent(MessageEvent event){
    int index = event.positioin;
  // do something using index,比如刷新文章内容
}

d. 在发布者(即Headline Fragment或者说Fragment A)中,在合适的地方执行post方法,即发布出去这个MessageEvent,这里即在HeadLineFragment的listview被点击的回调中发送post:

//HeadLineFragment.java

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {       
  EventBus.getDefault().post(new MessageEvent(position));
}

这样子,DetailFragment的onEvent方法就会被调用,含有position的MessageEvent也就被传了过去,随之DetailFragment根据拿到的position来刷新界面。

大功告成,这里可以发现两个fragment没有写任何的interface也没implements任何的接口,也不用实例化一个listenser并且执行所谓的setonlistener。

这里的内部流程大致是,EventBus在某个组件中注册的时候回记录下这个组件里面的onEvent函数,一个应用中可能有多个onEvent函数等待被调用,这里即通过onEvent函数的参数类型和个数来区别。

使用时需要注意一个问题,这里EventBus是通过java反射机制来找到这个onEvent方法的,所以打包的时候若需要混淆的话千万记住不要混淆onEvent这个函数,可以在proguard文件中添加:

-keepclassmembers class ** {
    public void onEvent*(**);
}

关于EventBus更多使用方法以及源码可以参考

https://github.com/greenrobot/EventBus/blob/master/HOWTO.md

相关推荐