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

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

可以看出,这个界面有一个数据源,一个适配器,一个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. Python--matplotlib绘图可视化知识点整理

    from:https://segmentfault.com/a/1190000005104723 本文作为学习过程中对matplotlib一些常用知识点的整理,方便查找. 强烈推荐ipython无论你 ...

  2. java模拟一个简单的QQ

    v 项目源码 https://github.com/hjzgg/java_QQ v 标题效果       package testFour; import java.awt.Color; import ...

  3. 企业云部署要如何选择IaaS PaaS和SaaS

    1为什么IaaS成了灵丹妙药   我非常惊讶,为什么很多传统企业已经接受了云计算,但接受的方式却往往不尽人意.对大多数企业来说,云计算的投入产出比相对较小,并且局限于基础设施层的环节. 就目前而言,大 ...

  4. php的SAPI,CLI SAPI,CGI SAPI

    首先一个问题:在命令行下执行:php -r 'echo 12;' 控制台会打印出 12: 这个过程不是很奇妙么,我输入的是shell命令,但是执行的却是php脚本.php脚本执行完成之后的输出还能在控 ...

  5. springMVC源码分析之拦截器

    一个东西用久了,自然就会从仅使用的层面上升到探究其原理的层面,在javaweb中springmvc更是如此,越是优秀的框架,其底层实现代码更是复杂,而在我看来,一个优秀程序猿就相当于一名武林高手,不断 ...

  6. BZOJ1008 /乘法原理+快速幂 解题报告

    1008: [HNOI2008]越狱 Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生 ...

  7. [操作系统实验lab4]实验报告

    实验概况 在开始实验之前,先对实验整体有个大概的了解,这样能让我们更好地进行实验. 我们本次实验需要补充的内容包括一整套以sys开头的系统调用函数,其中包括了进程间通信需要的一些系统调用如sys_ip ...

  8. SpringMVC核心——参数获取与Servlet资源获取问题

    一.SpringMVC 使用 @PathVariable.@RequestParam.@RequestHeader.@CookieValue 等来解决参数获取问题. 1. @PathVariable: ...

  9. 组合数学 - 母函数的运用 --- hdu 1709 :The Balance

    The Balance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. AEAI Portal V3.5.2门户集成平台发版说明

    AEAI Portal门户集成平台为数通畅联的核心产品,本着分享传递的理念,数通畅联将Portal_server.Portal_portlet两个项目开源,目的在于满足客户与伙伴的OEM需求,以及为广 ...