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

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

可以看出,这个界面有一个数据源,一个适配器,一个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. zk框架销毁Page上的Component

    销毁Page上的Component ZK的组件之间是树状结构的,每一组件都只有一个根. 从页面上销毁一个组件可以通过下面两种方式来实现: 1. 组件不是根组件时:Component.setParent ...

  2. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

  3. mysql按汉语拼音首字母排序

      如果数据表table的某字段name的字符编码是utf8_general_ci :   SELECT *  FROM `table` ORDER BY convert(name USING gbk ...

  4. Android学习笔记之蓝牙通信...

    PS:最近同学问我蓝牙的事,因此自己也就脑补了一下蓝牙... 学习内容: 1.如何实现蓝牙通信技术...   蓝牙通信其实是手机里很常用的一种通信方式,现在的手机中是必然存在蓝牙的,蓝牙通信也是有一部 ...

  5. MySQL 备份与还原详解

    相关阅读: MySQL备份和恢复具体实施 http://www.linuxidc.com/Linux/2012-12/76257.htm MySQL备份与恢复的三种方法总结 http://www.li ...

  6. [JS] jQuery选择器

    jQuery 选择器 选择器 实例 选取 * $("*") 所有元素 #id $("#lastname") id=lastname 的元素 .class $(& ...

  7. Java读取Excel文件的几种方法

    Java读取 Excel 文件的常用开源免费方法有以下几种: 1. JDBC-ODBC Excel Driver 2. jxl.jar 3. jcom.jar 4. poi.jar 简单介绍: 百度文 ...

  8. CheckListBox的实现方式分析

    实际项目中常常要实现有CheckBox列表框.但是WPF没有自带这样的一个控件,下面就用Style来实现这样的功能.而对于CheckBox列表框,又常常会有一个Select All的CheckBox来 ...

  9. 环信SDK与Apple Watch的结合(2)

    这一篇主要是介绍怎么拖apple watch上的相关页面,附源码EMWatchOCDemo. 需要在工程中的“EMWatchOCDemo WatchKit App”中进行操作,该文件夹的结构如图 Wa ...

  10. C#设计模式——适配器模式(Adapter Pattern)

    一.概述在软件开发中,常常会想要复用一个已经存在的组件,但该组件的接口却与我们的需要不相符,这时我们可以创建一个适配器,在需复用的组件的接口和我们需要的接口间进行转换,从而能够正常的使用需复用的组件. ...