Android设计模式系列(9)--SDK源码之适配器模式

简介: 原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2012/02/27/2010965.html对于android开发者来说起,适配器模式简直太熟悉不过,有很多应用可以说是天天在直接或者间接的用到适配器模式,比如ListView。

原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2012/02/27/2010965.html

对于android开发者来说起,适配器模式简直太熟悉不过,有很多应用可以说是天天在直接或者间接的用到适配器模式,比如ListView。
ListView用于显示列表数据,但是作为列表数据集合有很多形式,有Array,有Cursor,我们需要对应的适配器作为桥梁,处理相应的数据(并能形成ListView所需要的视图)。
正是因为定义了这些适配器接口和适配器类,才能使我们的数据简单灵活而又正确的显示到了adapterview的实现类上。
适配器模式,Adapter Pattern,勇敢的去适配,大量的资源可以重用。

1.意图
适配器模式,把一个类的接口变换成客户端所期待的另一种接口,从而使原本不匹配而无法在一起工作的两个,类能够在一起工作。
适配器模式分为类适配器模式和对象适配器模式。
关于类适配器模式,因为java的单继承,如果继承一个类,另外的则只能是接口,需要手动实现相应的方法。
热门词汇:类的适配器模式 对象的适配器模式 缺省适配器模式 源类 目标接口

2.结构图和代码

为了简明直接,我省略了相关的其他适配器 ,只以此两个适配器为例。
ListViews做为client,他所需要的目标接口(target interface)就是ListAdapter,包含getCount(),getItem(),getView()等几个基本的方法,为了兼容List<T>,Cursor等数据类型作为数据源,我们专门定义两个适配器来适配他们:ArrayAdapter和CursorAdapter。这两个适配器,说白了,就是针对目标接口对数据源进行兼容修饰。
这就是适配器模式。
其中BaseAdapter实现了如isEmpty()方法,使子类在继承BaseAdapter后不需要再实现此方法,这就是缺省适配器,这也是缺省适配器的一个最明显的好处。 

我们以最简单的若干个方法举例如下,ListAdapter接口如下(,为了简单,我省略了继承自Adapter接口):

public interface ListAdapter {
    public int getCount();
    Object getItem(int position);
    long getItemId(int position);
    View getView(int position, View convertView, ViewGroup parent);
    boolean isEmpty();
}

抽象类BaseAdapter,我省略其他代码,只列出两个方法,以作示意:

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
    // ... ...
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return getView(position, convertView, parent);
    }
    public boolean isEmpty() {
        return getCount() == 0;
    }
}

ArrayAdapter对List<T>进行封装成ListAdapter的实现,满足ListView的调用:
publicclass ArrayAdapter<T> extendsBaseAdapter implementsFilterable {
    privateList<T> mObjects;
    //我只列出这一个构造函数,大家懂这个意思就行
    publicArrayAdapter(Context context, inttextViewResourceId, T[] objects) {
        init(context, textViewResourceId, 0, Arrays.asList(objects));
    }
    privatevoid init(Context context, intresource, inttextViewResourceId, List<T> objects) {
        mContext = context;
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mResource = mDropDownResource = resource;
        mObjects = objects; //引用对象,也是表达了组合优于继承的意思
        mFieldId = textViewResourceId;
    }
    publicint getCount() {
        returnmObjects.size();
    }
   publicT getItem(intposition) {
        returnmObjects.get(position);
    }
    publicView getView(intposition, View convertView, ViewGroup parent) {
        returncreateViewFromResource(position, convertView, parent, mResource);
    }
    // ... ...
}


 我们就如此成功的把List<T>作为数据源以ListView想要的目标接口的样子传给了ListView,同理CursorAdapter也是一模一样的道理,就不写具体代码了。

    适配器本身倒是不难,但是提供了解决不兼容问题的惯用模式。 
    关于什么时候使用适配器模式,大概有三种情况:
    (1). 你想使用一个已经存在的类,而它的接口不符合你的需求,这个在处理旧系统时比较常见。
    (2). 你想创建一个可以复用的类,该类可以和其他不相关的类或不可预见的累协同工作,这就是我们android开发者经常碰到的情况:我们常常自定义一个新的Adapter。
    (3). 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配他们的接口,对象适配器可以适配他的父类接口。 

3.效果
1. 结构性模式 
2. 上面论述的主要是对象适配器,关于类适配器除了实现目标端口外,还要实现你要兼容的源类,这样可以少写几行代码,但是从组合优于继承的角度看,它总则没有那么的干净。
3. 对同一个适配器(即同一个对象)对同样的源进行双向甚至多向的适配,则能使其适用两个甚至多个客户调用。

相关文章
|
2月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
490 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
设计模式 存储 人工智能
194 0
|
5月前
|
设计模式 存储 缓存
Netty源码—9.性能优化和设计模式
本文主要介绍了Netty的两大性能优化工具、FastThreadLocal的源码和总结、Recycler的设计理念/使用/四个核心组件/初始化/对象获取/对象回收/异线程收割对象和总结,以及Netty设计模式的单例模式和策略模式。
203 53
|
6月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
433 2
|
6月前
|
设计模式 前端开发 Java
【设计模式】【结构型模式】适配器模式(Adpter)
一、入门 什么是适配器模式? 适配器模式是Java中常用的结构型设计模式,它的核心作用就像现实中的电源转换器一样---让原本不兼容的两个接口能够协同工作。 为什么要用适配器模式? 假设我们需要在电商系
168 10
|
7月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
9月前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
205 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
9月前
|
设计模式 存储 算法
「全网最细 + 实战源码案例」设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,将请求封装成独立对象,从而解耦请求方与接收方。其核心结构包括:Command(命令接口)、ConcreteCommand(具体命令)、Receiver(接收者)和Invoker(调用者)。通过这种方式,命令的执行、撤销、排队等操作更易扩展和灵活。 适用场景: 1. 参数化对象以操作。 2. 操作放入队列或远程执行。 3. 实现回滚功能。 4. 解耦调用者与接收者。 优点: - 遵循单一职责和开闭原则。 - 支持命令组合和延迟执行。 - 可实现撤销、恢复功能。 缺点: - 增加复杂性和类数量。
305 14
「全网最细 + 实战源码案例」设计模式——命令模式
|
9月前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
306 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
9月前
|
设计模式 SQL 算法
「全网最细 + 实战源码案例」设计模式——模板方法模式
模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。
234 7
「全网最细 + 实战源码案例」设计模式——模板方法模式