首先让我们看一个客户端图片

这是京东客户端的购物车界面。有这么一种功能,当我们在商品列表中调整商品数量等信息的时候,下方的金额总数也随之变化。

可以看出,这个界面有一个数据源,一个适配器,一个ListView。 总金额的布局是显示在ListView布局上面的。

那么怎么样可以当列表数据源变化的时候,下方的总金额(ListView 之外的UI)也变化?

有两个思路:

1、我们点击某一个列表项的某一个按钮时(可能是删除此商品按钮,可能是调整此商品数量按钮)的时候,对应执行监听事件接口回调的时候计算一下列表数据源数据得到的总金额。显示在UI中。 但是这种方法当列表项中能决定总金额的按钮比较多的时候,就会造成代码冗余。

2、给适配器设定一个观察者。当数据源发生变化的时候,观察者观察到并执计算总金额修改UI

我们这里学习第二种思路。

------------------------------------------------------------------------------------------------------------

一、首先,让我们看一下观察者模式的介绍:

观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
 
二、Adapter本身包含一个观察者模式 DataSetObserver
注意:DataSetObserver 是一个抽象类,使用的时候需要创建子类,不是接口。
Adapter可以注册多个数据观察者 registerDataSetObserver
 
三、DataSetObserver的使用
1、创建观察者对象
 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,查看总金额变化

 package com.xqx.adapterobserver;

 import android.app.Activity;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import org.w3c.dom.Text; import java.util.ArrayList;
import java.util.List; public class MainActivity extends Activity {
/**
* Called when the activity is first created.
*/ private ArrayAdapter<Integer> adapter ;
private List<Integer> list;
private ListView listView;
private TextView text; //创建观察者
private DataSetObserver sumObserver = new DataSetObserver() {
/**
* 当Adapter的notifyDataSetChanged方法执行时被调用
*/
@Override
public void onChanged() {
super.onChanged();
//执行相应的操作
int sum = ;
for (int i = ; i < list.size(); i++) {
sum+=list.get(i);
}
text.setText("总金额:"+sum);
} /**
* 当Adapter 调用 notifyDataSetInvalidate方法执行时被调用
*/
@Override
public void onInvalidated() {
super.onInvalidated();
//执行相应的操作
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); list = new ArrayList<Integer>();
for (int i = ; i < ; i++) {
list.add();
}
adapter = new ArrayAdapter<Integer>(this,android.R.layout.simple_list_item_1,list);
//注册观察者
adapter.registerDataSetObserver(sumObserver);
text = (TextView) findViewById(R.id.text);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
list.set(i,);
//将列表项的0变为2 更新适配器,
adapter.notifyDataSetChanged();
//执行该方法后DataSetObserver观察者观察到
}
}); } @Override
protected void onDestroy() {
super.onDestroy();
//注销观察者
adapter.unregisterDataSetObserver(sumObserver);
}
}

MainActivity.java

 <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
> </ListView> <LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#ccc"
android:layout_gravity="bottom"
>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="#000"
android:text="总金额"
/>
</LinearLayout> </FrameLayout>

main.xml

效果图:

浅谈Adapter中观察者模式的更多相关文章

  1. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  2. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  3. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  4. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  5. 转【】浅谈sql中的in与not in,exists与not exists的区别_

    浅谈sql中的in与not in,exists与not exists的区别   1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...

  6. 浅谈iOS中的userAgent

    浅谈iOS中的userAgent   User-Agent(用户代理)字符串是Web浏览器用于声明自身型号版本并随HTTP请求发送给Web服务器的字符串,在Web服务器上可以获取到该字符串. 在公司产 ...

  7. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  8. 浅谈sql中的in与not in,exists与not exists的区别

    转 浅谈sql中的in与not in,exists与not exists的区别   12月12日北京OSC源创会 —— 开源技术的年终盛典 »   sql exists in 1.in和exists ...

  9. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

随机推荐

  1. c# dataGridview的Cellclick移除事件

    private void gvMoldInfo_CellClick(object sender, DataGridViewCellEventArgs e) { ) return; string col ...

  2. 将main方法打成jar包,并引用第三方的maven jar包

    一.准备工作.执行命令 学习插件: 学习apache的打包插件maven-assembly-plugin:http://maven.apache.org/plugins/maven-assembly- ...

  3. PIN码计算锦集

    1. 腾达,C8:3A:35开头的MAC有效~network路由,MAC有效~以及00B00C开头的MAC有效之外的请您自己发现算法..这里只公布三个MAC地址算法,其余也可以算~这里就不公布出来了. ...

  4. [转载]Windows 2012 R2安装SharePoint 2013 手动安装工具软件

    之前介绍过在window 2012中安装SharePoint 2013,这次,借着SharePoint 2013 sp1补丁发布之际,介绍下在window 2012 r2中安装SharePoint 2 ...

  5. 网游中的网络编程3:在UDP上建立虚拟连接

    目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网络编程3:在UDP上建立虚拟连接 TODO 二.在UDP上建立虚拟连接 介绍 UDP是无连接的,一 ...

  6. Html5+css3+angularjs+jquery+webAPi 开发手机web(一)

    前言 随着浏览器的发展 HTML5+CSS3 的使用也越来越广泛,一直想学这个,想学那个折腾下来几乎没学到什么东西.工作经验告诉我,要掌握一门技术,就需要在项目中去磨练, 所以我就准备开发一个手机端的 ...

  7. hibernate集成

    hibernate是一个优秀的持久化框架负责简化将对象保存到数据库中,或从数据库中读取数据并封装到对象的工作.hibernate通过简单配置和编码即可替代jdbc繁琐的程序代码. 下面是集成hiber ...

  8. Scrum项目5.0

    1.团队成员完成自己认领的任务. 2.燃尽图:理解.设计并画出本次Sprint的燃尽图的理想线.参考图6. 3.每日立会更新任务板上任务完成情况.燃尽图的实际线,分析项目进度是否在正轨.    每天的 ...

  9. Linq之select子句

    在Linq中select子句用来指定查询结果的类型和表现形式.Linq查询要么以select子句结尾,要么以group子句结尾. List<UserBaseInfo> users = ne ...

  10. Winform开发框架之统计图表的实现

    在前面的一些随笔中,介绍了不少我的Winform框架的特性,上篇随笔<Winform开发框架之通用高级查询模块>对其中的通用高级模块进了一个整理说明,本篇继续介绍Winform开发框架重要 ...