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

    xiaoxiao2021-04-01  32

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

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

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

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

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

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

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

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

    [java]  view plain  copy 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;           }          }   }  

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

    转载请注明原文地址: https://ju.6miu.com/read-665636.html

    最新回复(0)