浅谈Adapter中观察者模式
首先让我们看一个客户端图片
这是京东客户端的购物车界面。有这么一种功能,当我们在商品列表中调整商品数量等信息的时候,下方的金额总数也随之变化。
可以看出,这个界面有一个数据源,一个适配器,一个ListView。 总金额的布局是显示在ListView布局上面的。
那么怎么样可以当列表数据源变化的时候,下方的总金额(ListView 之外的UI)也变化?
有两个思路:
1、我们点击某一个列表项的某一个按钮时(可能是删除此商品按钮,可能是调整此商品数量按钮)的时候,对应执行监听事件接口回调的时候计算一下列表数据源数据得到的总金额。显示在UI中。 但是这种方法当列表项中能决定总金额的按钮比较多的时候,就会造成代码冗余。
2、给适配器设定一个观察者。当数据源发生变化的时候,观察者观察到并执计算总金额修改UI
我们这里学习第二种思路。
------------------------------------------------------------------------------------------------------------
一、首先,让我们看一下观察者模式的介绍:
private DataSetObserver sumObserver = new DataSetObserver() { /** * 当Adapter的notifyDataSetChanged方法执行时被调用 */ @Override public void onChanged() { super.onChanged();
//执行相应的操作 } /** * 当Adapter 调用 notifyDataSetInvalidate方法执行时被调用 */ @Override public void onInvalidated() { super.onInvalidated();
//执行相应的操作 } };
2、注册观察者
在onCreat()方法中
//设置Adapter的数据变化观察者,只要Adapter的notifyDataSet被调用,观察者自动调用 adapter.registerDataSetObserver(sumObserver);
3、注销观察者
在适当的位置注销观察者
比如在onDestroy()方法中注销
@Override protected void onDestroy() { super.onDestroy(); adapter.unregisterDataSetObserver(sumObserver); }
四、Demo
当ListView数据源发生变化时UI发生变化。初始所有列表项都为0,点击变为2,查看总金额变化
1 package com.xqx.adapterobserver; 2 3 import android.app.Activity; 4 import android.database.DataSetObserver; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.widget.*; 8 import org.w3c.dom.Text; 9 10 import java.util.ArrayList; 11 import java.util.List; 12 13 public class MainActivity extends Activity { 14 /** 15 * Called when the activity is first created. 16 */ 17 18 private ArrayAdapter<Integer> adapter ; 19 private List<Integer> list; 20 private ListView listView; 21 private TextView text; 22 23 //创建观察者 24 private DataSetObserver sumObserver = new DataSetObserver() { 25 /** 26 * 当Adapter的notifyDataSetChanged方法执行时被调用 27 */ 28 @Override 29 public void onChanged() { 30 super.onChanged(); 31 //执行相应的操作 32 int sum = 0; 33 for (int i = 0; i < list.size(); i++) { 34 sum+=list.get(i); 35 } 36 text.setText("总金额:"+sum); 37 } 38 39 /** 40 * 当Adapter 调用 notifyDataSetInvalidate方法执行时被调用 41 */ 42 @Override 43 public void onInvalidated() { 44 super.onInvalidated(); 45 //执行相应的操作 46 } 47 }; 48 @Override 49 public void onCreate(Bundle savedInstanceState) { 50 super.onCreate(savedInstanceState); 51 setContentView(R.layout.main); 52 53 list = new ArrayList<Integer>(); 54 for (int i = 0; i < 30; i++) { 55 list.add(0); 56 } 57 adapter = new ArrayAdapter<Integer>(this,android.R.layout.simple_list_item_1,list); 58 //注册观察者 59 adapter.registerDataSetObserver(sumObserver); 60 text = (TextView) findViewById(R.id.text); 61 listView = (ListView) findViewById(R.id.listView); 62 listView.setAdapter(adapter); 63 64 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 65 @Override 66 public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 67 list.set(i,2); 68 //将列表项的0变为2 更新适配器, 69 adapter.notifyDataSetChanged(); 70 //执行该方法后DataSetObserver观察者观察到 71 } 72 }); 73 74 } 75 76 @Override 77 protected void onDestroy() { 78 super.onDestroy(); 79 //注销观察者 80 adapter.unregisterDataSetObserver(sumObserver); 81 } 82 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <ListView 8 android:id="@+id/listView" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent" 11 > 12 13 </ListView> 14 15 <LinearLayout 16 android:layout_width="match_parent" 17 android:layout_height="50dp" 18 android:background="#ccc" 19 android:layout_gravity="bottom" 20 > 21 <TextView 22 android:id="@+id/text" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:textSize="25sp" 26 android:textColor="#000" 27 android:text="总金额" 28 /> 29 </LinearLayout> 30 31 </FrameLayout>
效果图:
作者:听着music睡
出处:http://www.cnblogs.com/xqxacm/
Android交流群:38197636
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。