本文共 3329 字,大约阅读时间需要 11 分钟。
有时候我们会有这么一个需求,在Listview的某个Item上有个按钮,点击这个按钮之后呢,需要对其它的item做一些操作,就像下面这个:
采纳按钮点击之前:采纳按钮点击之后:
简单介绍一下这两张图的意思:
模拟了一个Listview,在每个Item上都有一个“采纳”按钮,当点击其中一个“采纳”之后,需要将其它“采纳”按钮隐藏,并且自身需要改为“已采纳”,如后面的图所示。
我们有一种简单的办法可以做到,就是更改数据的值,并且让Adapter重新刷新一遍,这是一种简单粗暴的方式,用户体验非常不好,会使整个页面都闪一下。
那么为了有没有什么更好的办法呢?有的,使用我们的观察者模式。
观察者模式在我们这里的基本实现方式是:当其中一个按钮被点击之后,通过回调更新其它控件即可。如何实现呢?以简单代码来说明:
package com.sahadev;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.os.Message;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ListView;import com.lidroid.xutils.ViewUtils;import com.lidroid.xutils.view.annotation.ViewInject;import com.sahadev.renren.R;public class MainActivity extends Activity { @ViewInject(R.id.listview) private ListView listview; private BaseAdapter internalAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_zoom); ViewUtils.inject(this); internalAdapter = new InternalAdapter(this); listview.setAdapter(internalAdapter); } /** * 观察者模式的回调接口 * * @author Sahadev * */ public interface Callback { public void update(Message msg); } private static class InternalAdapter extends BaseAdapter { private int dataSize = 6; private Map最后附上我们的运行效果图,是不是很实用呢?maps; private LayoutInflater inflate; public InternalAdapter(Context context) { super(); inflate = LayoutInflater.from(context); maps = new HashMap (); } @Override public int getCount() { return dataSize; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @SuppressLint("InflateParams") @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflate.inflate(R.layout.listview_item_layout, null); Button button = (Button) convertView.findViewById(R.id.button); // 生成一个观察者 Callback callback = new Callback() { @Override public void update(Message msg) { // 当其中一个按钮被点击时通过调用update方法来更新其它UI // 先隐藏所有的采纳按钮 View view = (View) msg.obj; if (msg.what == 0) { view.setVisibility(View.INVISIBLE); } else { Button button = (Button) view; button.setText("已采纳"); button.setEnabled(false); } } }; // 将我们的需要更改的对象和观察者一并放入maps maps.put(button, callback); button.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { // 遍历maps中所有的监听者 Set > entrySet = maps.entrySet(); Iterator > iterator = entrySet.iterator(); while (iterator.hasNext()) { Entry next = iterator.next(); // 使用value的update方法将key作为参数使得监听的地方对它进行修改 Message msg = new Message(); View temp = next.getKey(); msg.obj = temp; if (temp.equals(v) || temp == v) {// 如果是点击的按钮本身,则需要对它进行特殊处理 msg.what = 1; } // 通知所有的观察者 next.getValue().update(msg); } } }); } return convertView; } }}