您的位置:首页 > 其它

用EventBus传值,来实现局部更新listview的item

2018-03-14 14:01 267 查看

前言

最近在做一个小需求,是在一个listview的item上有一个区分性别的图片,和一个状态文本,如图:


在点击item的查看按钮时,进入下一个页面,如图:


该页面也有一个性别图片,和一个修改按钮,点击修改按钮展示一个dialog,里面可以选择性别,然后实时的更新页面,拿到需求后,本来想的是按照以往的做法,在请求成功后通过OnActivityforResult()方法,设置resultCode值,来刷新整个页面,但是在看到IOS同事得实现后,是直接单点刷新,虽然以前也知道Android可以实现,但是本人比较懒,一直没有去这么做。。。

本篇只是用的EventBus这个简单的框架,如果还没用过这个得伙伴,建议试用一下,相当不错,网上一大堆教程,我在这都给出来,省的大家再去找。

首先介绍下EventBus

EventBus是greenrobot在Android平台发布的一款以订阅——发布模式为核心的开源库。EventBus翻译过来是事件总线的意思,可以这样理解:一个个事件(event)发送到总线上,然后EventBus根据已注册的订阅者(subscribers)来匹配相应的事件,进而把事件传递给订阅者,这也是观察者模式的一个最佳实践。

那么EventBus可以用到什么地方呢?我们平时开发的时候,当遇到Activity与Activity、Activity与Fragment之间的通信,往往采用Intent,又或者线程之间使用Handler进行通信,这样代码难免会复杂许多,而使用EventBus能极大简化两个组件之间的通信问题,而且效率极高,而EventBus升级到3.0版本后,开发者能够自定义订阅方法的名字,而没必要规定以“onEventXX”开头的方法了,这样也自由化了很多,而且支持了粘性事件的分发等,因此学会使用EventBus3.0对我们的开发有极大的好处。

第一步:依赖包

去GitHub找EventBus地址

在Android Studio中添加如下依赖:

compile ‘org.greenrobot:eventbus:3.0.0’

第二步:使用

在准备好EventBus后,我们通过我的需求来展示它的使用方法。实现的例子很简单,主要是在Activity1中打开Activity2,而Activity2中通过点击按钮来使Activity1中的ImageView显示内容得到更改,而显示的内容由Activity2指定。这便构成了一个典型的Activity与Activity之间通信的场景,如果用我们之前的做法可以采用BroadcastReceiver来实现两者的通信,但现在我们使用EventBus,只需要几行代码就能实现了,而且还可以由Activity和Fragment之间的通信。具体使用我在后续代码中会告诉大家,我使用的是Activity和Fragment之间传值,

首先我在第二个页面Activity的dialog按钮选择性别并保存后,会调用一个接口,这个相信大家都会明白,然后在接口给我成功的结果后,用EventBus传递一个自己写的值如图:


EventBus.getDefault().post(new SubmitEvent(sex));该方法就是我传的值,很简单,这个SubmitEvent类是这样的:

public class SubmitEvent {

private String message;

public SubmitEvent(String message) {
this.message = message;
}

public String getMessage() {
return message;
}


}

就是一个很简单的字符串的自定义类

由于我的Fragment里面装载的是一个listview,所以单独把adapter抽取了出来了,所以下面的代码是adapter类里面的方法,首先我给这个item的点击事件跳转的时候把对应的position传过去,加粗的代码:

//点击填写操作

holder.tvStatus.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

position = i;

if (firtCommunicate == 1){

FirstCommunicationActivity.open(context,model.studentId,”2”,model.year,model.term);

}else {

FirstCommunicationActivity.open(context,model.studentId,”“,”“,”“);

}

}

});

然后在该Fragment类里,在onCreateView方法里注册EventBus,加粗代码:

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_new, null);//加载布局

EventBus.getDefault().register(this);// 注册EventBus

listView = (ListView) view.findViewById(R.id.list_view);

rootView = (ViewGroup) view.findViewById(R.id.rootView);

initView();//加载页面

return view;

}

再在onDestroy方法里去注销:

@Override

public void onDestroy() {

super.onDestroy();

EventBus.getDefault().unregister(this);//注销EventBus

}

然后主要的代码就要登场了,下面的代码是接收传递过来的值,通用的方法,该方法就是接收EventBus传值的,是EventBus的方法

//订阅方法,当接收到事件的时候,会调用该方法

@Subscribe(threadMode = ThreadMode.MAIN)

public void onEvent(SubmitEvent messageEvent){

updateData(myAdapter.position , messageEvent.getMessage());

}

然后下面的代码就是更新要变化的view代码:

/**

* 单独更新组件

* @param position 更新组件的下标

*/

public void updateData(int position,String message) {

//获取对应position的数据

NewVersionNewStudentModel models = studentList.get(position);

//将传过来的值赋值给它

models.sex = message;

//获取当前显示项的第一行和最后一行

int firstVisible = listView.getFirstVisiblePosition();

int lastVisible = listView.getLastVisiblePosition();

//获取该行的view(因为listView仅会维护当前的显示项,所以根据下标获取时,0为当前显示行

// 的第一行即firstVisible,所以获取当前行应该用当前行减去firstVisible)

View view = listView.getChildAt(position - firstVisible);

if (view != null) { //若获取的时候该行被滑出屏幕则会返回空

//获取viewHolder

ImageView iv_sex = (ImageView) view.findViewById(R.id.iv_sex);//性别

//学生性别

if (null != message && !”“.equals(message)){

if (“1”.equals(message)){

iv_sex.setVisibility(View.VISIBLE);

iv_sex.setImageResource(R.mipmap.icon_man);

}else if (“0”.equals(message)){

iv_sex.setVisibility(View.VISIBLE);

iv_sex.setImageResource(R.mipmap.icon_women);

}else {

iv_sex.setVisibility(Vi
4000
ew.GONE);

}

}else {

iv_sex.setVisibility(View.GONE);

}

}

}

到这里整个功能就实现了,是不是第一眼看感觉很麻烦,其实很简单的,还有欢迎大家指正,希望能帮到需要的同学,和有更好的方法的也可以大家一起分享出来,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  安卓开发