(转)设计模式之观察者模式在ListView中的应用

来源:互联网 发布:软件怎么挣钱 编辑:程序博客网 时间:2024/05/20 23:59

原地址:http://blog.csdn.net/sahadev_/article/details/49464273


有时候我们会有这么一个需求,在Listview的某个Item上有个按钮,点击这个按钮之后呢,需要对其它的item做一些操作,就像下面这个:

采纳按钮点击之前:采纳按钮点击之后:

简单介绍一下这两张图的意思:

模拟了一个Listview,在每个Item上都有一个“采纳”按钮,当点击其中一个“采纳”之后,需要将其它“采纳”按钮隐藏,并且自身需要改为“已采纳”,如后面的图所示。

我们有一种简单的办法可以做到,就是更改数据的值,并且让Adapter重新刷新一遍,这是一种简单粗暴的方式,用户体验非常不好,会使整个页面都闪一下。

那么为了有没有什么更好的办法呢?有的,使用我们的观察者模式。

观察者模式在我们这里的基本实现方式是:当其中一个按钮被点击之后,通过回调更新其它控件即可。如何实现呢?以简单代码来说明:

[java] view plain copy
  1. package com.sahadev;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Iterator;  
  5. import java.util.Map;  
  6. import java.util.Map.Entry;  
  7. import java.util.Set;  
  8.   
  9. import android.annotation.SuppressLint;  
  10. import android.app.Activity;  
  11. import android.content.Context;  
  12. import android.os.Bundle;  
  13. import android.os.Message;  
  14. import android.view.LayoutInflater;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.view.ViewGroup;  
  18. import android.widget.BaseAdapter;  
  19. import android.widget.Button;  
  20. import android.widget.ListView;  
  21.   
  22. import com.lidroid.xutils.ViewUtils;  
  23. import com.lidroid.xutils.view.annotation.ViewInject;  
  24. import com.sahadev.renren.R;  
  25.   
  26. public class MainActivity extends Activity {  
  27.     @ViewInject(R.id.listview)  
  28.     private ListView listview;  
  29.   
  30.     private BaseAdapter internalAdapter;  
  31.   
  32.     @Override  
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.activity_zoom);  
  36.   
  37.         ViewUtils.inject(this);  
  38.   
  39.         internalAdapter = new InternalAdapter(this);  
  40.   
  41.         listview.setAdapter(internalAdapter);  
  42.     }  
  43.   
  44.     /** 
  45.      * 观察者模式的回调接口 
  46.      *  
  47.      * @author Sahadev 
  48.      * 
  49.      */  
  50.     public interface Callback {  
  51.         public void update(Message msg);  
  52.     }  
  53.   
  54.     private static class InternalAdapter extends BaseAdapter {  
  55.         private int dataSize = 6;  
  56.         private Map<View, Callback> maps;  
  57.   
  58.         private LayoutInflater inflate;  
  59.   
  60.         public InternalAdapter(Context context) {  
  61.             super();  
  62.   
  63.             inflate = LayoutInflater.from(context);  
  64.             maps = new HashMap<View, MainActivity2.Callback>();  
  65.         }  
  66.   
  67.         @Override  
  68.         public int getCount() {  
  69.             return dataSize;  
  70.         }  
  71.   
  72.         @Override  
  73.         public Object getItem(int position) {  
  74.             return null;  
  75.         }  
  76.   
  77.         @Override  
  78.         public long getItemId(int position) {  
  79.             return 0;  
  80.         }  
  81.   
  82.         @SuppressLint("InflateParams")  
  83.         @Override  
  84.         public View getView(int position, View convertView, ViewGroup parent) {  
  85.             if (convertView == null) {  
  86.                 convertView = inflate.inflate(R.layout.listview_item_layout, null);  
  87.   
  88.                 Button button = (Button) convertView.findViewById(R.id.button);  
  89.   
  90.                 // 生成一个观察者  
  91.                 Callback callback = new Callback() {  
  92.   
  93.                     @Override  
  94.                     public void update(Message msg) {  
  95.                         // 当其中一个按钮被点击时通过调用update方法来更新其它UI  
  96.                         // 先隐藏所有的采纳按钮  
  97.                         View view = (View) msg.obj;  
  98.                         if (msg.what == 0) {  
  99.                             view.setVisibility(View.INVISIBLE);  
  100.                         } else {  
  101.                             Button button = (Button) view;  
  102.                             button.setText("已采纳");  
  103.                             button.setEnabled(false);  
  104.                         }  
  105.                     }  
  106.                 };  
  107.   
  108.                 // 将我们的需要更改的对象和观察者一并放入maps  
  109.                 maps.put(button, callback);  
  110.   
  111.                 button.setOnClickListener(new OnClickListener() {  
  112.   
  113.                     @Override  
  114.                     public void onClick(final View v) {  
  115.                         // 遍历maps中所有的监听者  
  116.                         Set<Entry<View, Callback>> entrySet = maps.entrySet();  
  117.                         Iterator<Entry<View, Callback>> iterator = entrySet.iterator();  
  118.                         while (iterator.hasNext()) {  
  119.                             Entry<View, Callback> next = iterator.next();  
  120.                             // 使用value的update方法将key作为参数使得监听的地方对它进行修改  
  121.                             Message msg = new Message();  
  122.                             View temp = next.getKey();  
  123.                             msg.obj = temp;  
  124.   
  125.                             if (temp.equals(v) || temp == v) {// 如果是点击的按钮本身,则需要对它进行特殊处理  
  126.                                 msg.what = 1;  
  127.                             }  
  128.                             // 通知所有的观察者  
  129.                             next.getValue().update(msg);  
  130.                         }  
  131.   
  132.                     }  
  133.                 });  
  134.             }  
  135.             return convertView;  
  136.         }  
  137.   
  138.     }  
  139. }  


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



0 0
原创粉丝点击