设计模式之观察者模式在Listview中的应用

简介: 有时候我们会有这么一个需求,在Listview的某个Item上有个按钮,点击这个按钮之后呢,需要对其它的item做一些操作,就像下面这个: 采纳按钮点击之前:采纳按钮点击之后: 简单介绍一下这两张图的意思: 模拟了一个Listview,在每个Item上都有一个“采纳”按钮,当点击其中一个“采纳”之后,需要将其它“采纳”按钮隐藏,并且自身需要改为“已采纳”,如后面的图所示。

有时候我们会有这么一个需求,在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<View, Callback> maps;

		private LayoutInflater inflate;

		public InternalAdapter(Context context) {
			super();

			inflate = LayoutInflater.from(context);
			maps = new HashMap<View, MainActivity2.Callback>();
		}

		@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<Entry<View, Callback>> entrySet = maps.entrySet();
						Iterator<Entry<View, Callback>> iterator = entrySet.iterator();
						while (iterator.hasNext()) {
							Entry<View, Callback> 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;
		}

	}
}


最后附上我们的运行效果图,是不是很实用呢?





目录
相关文章
|
1月前
|
设计模式 算法 C++
【C++ 泛型编程 进阶篇】C++元模板编程与设计模式的结合应用教程(二)
【C++ 泛型编程 进阶篇】C++元模板编程与设计模式的结合应用教程
26 0
|
29天前
|
设计模式 编解码 C++
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(一)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
47 0
|
3月前
|
设计模式 监控 安全
设计模式 | 观察者模式
设计模式 | 观察者模式
18 0
|
3月前
|
设计模式 前端开发 数据中心
设计模式之观察者模式
设计模式之观察者模式
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
29天前
|
设计模式 存储 缓存
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(二)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
27 0
|
16天前
|
设计模式 监控 Java
设计模式 - 观察者模式(Observer):Java中的战术与策略
【4月更文挑战第7天】观察者模式是构建可维护、可扩展系统的关键,它在Java中通过`Observable`和`Observer`实现对象间一对多的依赖关系,常用于事件处理、数据绑定和同步。该模式支持事件驱动架构、数据同步和实时系统,但需注意避免循环依赖、控制通知粒度,并关注性能和内存泄漏问题。通过明确角色、使用抽象和管理观察者注册,可最大化其效果。
|
1月前
|
设计模式 存储 Java
【设计模式】观察者模式
【设计模式】观察者模式
|
5天前
|
设计模式 算法 Java
Java中的设计模式及其应用
【4月更文挑战第18天】本文介绍了Java设计模式的重要性及分类,包括创建型、结构型和行为型模式。创建型模式如单例、工厂方法用于对象创建;结构型模式如适配器、组合关注对象组合;行为型模式如策略、观察者关注对象交互。文中还举例说明了单例模式在配置管理器中的应用,工厂方法在图形编辑器中的使用,以及策略模式在电商折扣计算中的实践。设计模式能提升代码可读性、可维护性和可扩展性,是Java开发者的必备知识。
|
27天前
|
设计模式 算法 中间件
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
113 1