`
dowhathowtodo
  • 浏览: 780998 次
文章分类
社区版块
存档分类
最新评论

android适配器模式设计与实现

 
阅读更多

适配器模式是一种重要的设计模式,在android中得到了广泛的应用。适配器类似于现实世界里面的插头,通过适配器,我们可以将分属于不同类的两种不同类型的数据整合起来,而不必去根据某一需要增加或者修改类里面的方法。

适配器又分为单向适配器和双向适配器,在android中前者使用的比较频繁。比较常见的实现方式是:首先定义一个适配类,内部定义一个私有的需要适配的对象,该类提供一个构造函数,将该对象的一个实例作为参数传入,并在构造函数里面进行初始化,再提供一个公有的方法,返回另外一个需要适配的类所需要的数据类型。这样通过创建一个额外的类,专门负责数据类型的转换,在不改动原有类的前提下实现了所需的功能。这种设计模式提供了更好的复用性和可扩展性,尤其在我们无法获修改其中一个类或者类与类之间有比较多的不同类型的数据需要进行适配的时候显得格外重要。

在android中常见的适配器类有:BaseAdapter、SimpleAdapter等,首先我们看看android应用层是如何使用适配器的:

以listview为例,我们设计一个简单的适配,效果如下:

新建工程创建一个名为AdapterTest的Activity,在main.xml里创建一个listview内容如下:

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"android:layout_width="fill_parent"

android:layout_height="fill_parent">

<ListViewandroid:id="@+id/min"android:layout_height="wrap_content"

android:layout_width="wrap_content"/>

</LinearLayout>



新建一个名为item的xml文件,里面对插入的数据进行布局,内容如下:

<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="horizontal"android:layout_width="fill_parent"

android:layout_height="wrap_content">

<ImageViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:id="@+id/malone"/>

<TextViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_vertical"

android:id="@+id/malone1"/>

</LinearLayout>

在AdapterTest类中定义两个静态全局数组,里面存放我们要显示的内容

publicstaticString[]mTitles= {"1","2","3","4"};

publicstaticint[]mIds= { R.drawable.icon, R.drawable.icon,

R.drawable.icon,

R.drawable.icon};

创建一个内部适配类MinAdapter继承BaseAdapter,需要实现四个方法:

getCount、getItem、getItemId、getView

我们先定义两个私有的数组,并在构造函数中初始化:

privateString[]titles;

privateint[]ids;

publicMinAdapter(String[] t,int[] idres) {

titles= t;

ids= idres;

}

实现其中的getCount和getView方法如下:

publicintgetCount() {

//TODOAuto-generated method stub

returntitles.length;

}

该回调方法返回listview中显示的行数

publicView getView(intposition, View convertView, ViewGroup parent) {

//TODOAuto-generated method stub

LayoutInflater l = LayoutInflater.from(AdapterTest.this);

View v = l.inflate(R.layout.item,null);

ImageView itemImage = (ImageView)v.findViewById(R.id.malone);

itemImage.setBackgroundResource(ids[position]);

((TextView)v.findViewById(R.id.malone1)).setText(titles[position]);

returnv;

}

getView是一个比较重要的回调方法,它返回position位置上的view。

在oncreate中设置adapter:

setContentView(R.layout.main);

ListView list = (ListView)findViewById(R.id.min);

MinAdapter adapter =newMinAdapter(mTitles,mIds);

list.setAdapter(adapter);

这样就实现了一个简单的adapter。

接下来我们对BaseAdapter的实现源码进行分析:

BaseAdapter是一个抽象类,实现了了ListAdapter和SpinnerAdapter两个接口,这两个接口都继承自Adapter接口。在这个接口中申明了我们需要实现的四个重要的方法。

接下来,我们进入ListView中查看setAdapter方法,ListView就是通过调用这个方法与适配器联系起来的。该方法的入参数为ListAdapter类型,ListAdapter同样继承了adapter,也就是说,我们只能够重写adapter中的一些回调方法才会起效。该方法中,首先会调用getCount方法来设置listitem的数目,进行一系列操作之后会调用requestLayout方法。由于ListView中并没有定义该方法,它会调用它的父类AbsListView中的requestLayout方法,该方法调用后会回调其中的onLayout方法,该方法会调用ListView中的layoutChildren方法,该方法会调用fillSpecific方法,fillSpecific方法,通过调用makeAndAddView方法得到需要view,然后将view放入list。查看makeAndAddView方法,它会调用父类的obtainView方法,而该方法会调用适配器中重写的getView方法。

child = mAdapter.getView(position, scrapView, this);或

child = mAdapter.getView(position,null,this);

另外一个比较常见的设置adapter的控件是Gallery,Gallery继承自AbsSpinner,该类内部提供了setAdapter方法,该方法的实现与listview类似,

通过mItemCount=mAdapter.getCount();得到item的数量

调用requestLayout();方法回掉onLayout方法,调用layout方法,该方法中调用makeAndAddView方法,里面可以找到我们熟悉的语句:

child =mAdapter.getView(position,null,this);

综合listview和gallery,发现它们有着类似的实现过程,在setAdapter里面获取适配的item的个数,然后通知各自的控件构造这些item,构造的时候会通过适配器来获取需要适配的view。

为了更简单地实现适配器的功能,android提供了一个更为方便的类SimpleAdapter进行适配。SimpleAdapter的构造函数如下:

publicSimpleAdapter(Context context, List<?extendsMap<String, ?>> data,intresource, String[] from,int[] to)

第一个参数是显示适配内容的activity的上下文,第二个参数看起来比较复杂,这是一个List类型的对象data,里面存放着一个继承自Map类型的任意对象,而这个Map中存放的第一个数据类型,即key值为String类型,第二个为任意类型,第三个参数是我们需要存放进去的item的layoutid,第四个参数为map中的key的集合,第五个参数为map中第二个参数在layout中对应的各自的id。

上述例子进行简单修改如下:

List<Map<String,Object>> list1 =newArrayList<Map<String,Object>>();

for(inti=0;i<mTitles.length;i++) {

Map<String,Object> m=newHashMap<String,Object>();

m.put("title",mTitles[i]);

m.put("icon", R.drawable.icon);

list1.add(m);

}

SimpleAdapter adapter =newSimpleAdapter(this,list1,R.layout.item,newString[]{"icon","title"},

newint[]{R.id.malone,R.id.malone1});

list.setAdapter(adapter);

即可实现同样的效果。

接下来查看SimpleAdapter源码:

其内部定义了一个私有的对象:

privateList<?extendsMap<String, ?>>mData;

并在构造的时候将其初始化。

SimpleAdapter重写了getCount、getView方法,完成了之前相同的功能

事实上,SimpleAdapter进行了一次简单的适配,将需要适配的数据统一转化为存有map数据的list,给开发者提供了统一的、方便的接口,让开发者使用起来更为方便。

分享到:
评论

相关推荐

    Android 适配器模式应用及设计原理

    适配器模式是一种重要的设计模式,在 Android 中得到了广泛的应用。适配器类似于现实世界里面的插头,通过适配器,我们可以将分属于不同类的两种不同类型的数据整合起来,而不必去根据某一需要增加或者修改类里面的...

    Android开发三剑客_part1

    下篇对单元测试用例 测试的生命周期 自动化测试等均进行深入的分析与讲解 并结合模板方法模式 适配器模式 组合模式等深入解析JUnit框架的设计和实现思路 part1 总共2部分"&gt;从整体上来看 一款Android产品分为设计 ...

    Android代码-ExamplesOfDesignPatterns

    各种设计模式的Uml图、分析与代码实现,主要在dev分支。 所有模式的Uml图都在XMindDescribe目录下的xmind文件里 项目结构 名字 描述 action 行为型设计模式 create 创建型设计模式 structure 结构型设计...

    Android开发三剑客_part2

    下篇对单元测试用例 测试的生命周期 自动化测试等均进行深入的分析与讲解 并结合模板方法模式 适配器模式 组合模式等深入解析JUnit框架的设计和实现思路 part2 总共2部分"&gt;从整体上来看 一款Android产品分为设计 ...

    Android控件系列之相册GalleryAdapter适配器入门控件缩放动画入门

    学习目的: 1、掌握在Android中如何建立Gallery 2、初步理解Android适配器的原理 3、实现简单的控件缩放动画 简介: 1、Gallery是Android内置的一个控件,它可以继承若干图片甚至是其他控件 2、Gallery自带了滚动...

    精通ANDROID 3(中文版)1/2

    第1章 Android计算平台简介  1.1 面向新PC的全新平台  1.2 Android的历史  1.3 Dalvik VM剖析  1.4 理解Android软件栈  1.5 使用Android SDK开发最终用户应用程序  1.5.1 Android模拟器  1.5.2 ...

    《Android应用开发》个人总结报告.doc

    尽管例子之间的连接 比较零散,不过通过这些例子的学习我可以学习到了很多和以前java上相通的思想,因 为Android在现在也是全新的技术和框架,在其中我也学到了如何用单例模式、工厂模式 等常用的设计模式进行学习,...

    Android实训实习报告总结.docx

    如对话框背景等,或去google code找些开源的代码下来研究,学习人家的设计思想、模块功能的划分、代码组织结构等知识 这个过程中,涉及到的知识比较多,如版本管理工具SVN、Git、Mercurial,如设计模式Android实训...

    精通Android 3 (中文版)2/2

    第1章 Android计算平台简介  1.1 面向新PC的全新平台  1.2 Android的历史  1.3 Dalvik VM剖析  1.4 理解Android软件栈  1.5 使用Android SDK开发最终用户应用程序  1.5.1 Android模拟器  1.5.2 ...

    moment:探索Android最新架构,最前沿的技术

    适配器模式:使用适配器将横幅数据绑定到查看上 框架分析 组成作品使用撰写版本进行预先统一配置 数据存储1.使用DataStore存储简单键值对数据2.使用DataStore存储protobuf序列化的对象 启动使用start

    AlbumSample:用于列出与音乐专辑相关的元数据的示例 Android 项目

    观察者模式设计实现。 用于异步下载图像的新 API。 文件和内存缓存实现平滑滚动,快速加载图像,并存储最近的图像,节省重新下载的工作量。 UI 更改,用于向用户显示当前上下文。 在操作栏中单击主页时打开抽屉...

    招银网络java科技笔试题-WaytoInterview:JVM和设计模式和算法的快速浏览

    适配器模式 过滤器模式 代理模式 MVC模式 策略模式 Algorithm 剑指Offer上的算法题目的Java实现 常用排序算法 Leetcode IsomorphicStrings_lc205 lowestCommonAncestor_lc235 Netease 2018 - 2019 年度网易Android、...

    cs413sp15team01p4

    (DI) 模型-视图-适配器 (MVA) 架构模式将 MVA 映射到 Android MVA 和模型-视图-控制器 (MVC) 之间的区别区分哑、React和自主模型组件关键设计模式使用观察者模式实现事件驱动的行为使用状态模式实现依赖状态的行为将...

    Aflux:传感器数据收集应用

    Aflux不仅仅是一个功能齐全的数据收集系统,它还是一种设计模式的原型,我们相信它可以简化android开发过程。 这个想法是实现PURE java机制。 该系统分为四个部分: 核 资料库 Ui 4.片段5.适配器6.目的过滤器7....

    android-movie-app:使用Kotlin的Android电影应用

    使用MVVM设计模式+ + 构建Android 使用依赖注入( )来分离配置(属性,imageClient,httpClient等)和UI使用情况 在活动/片段中使用进行视图注入 使用和调用RESTful API并解析返回的JSON响应 作为Retrofit2呼叫...

    java类源码-Java_Design:HeadFirstDesignPatterns是一本通俗、细致、容易理解的设计模式书籍,整理书中涉及的

    1、适配器模式 包装一个对象,来提供不同的接口 2、代理模式 代理对象持有被代理对象的引用,通过代理对象简介访问被代理对象,来控制对被代理对象的访问(重点学习动态代理涉及反射知识) 动态代理弥补了普通代理...

    自定义的月历视图控

    该源码案例实现了可以支持自定义的月历视图控,源码MonthView,用于Android开发中自定义的月历视图控件,使用简单,可以很方便自定义各种漂亮的风格。 适配器模式设计,性能优良。

    udacity-app-portfolio:为Android Nanodegree创建应用程序组合

    udacity-app-portfolio 为Android Nanodegree创建应用程序组合 在最初的设计中,我试图复制Play商店的用户... 应用程序列表当前未实现为适配器,并且不允许滚动,因此在横向模式下,该列表当前已被切断并且无法滚动。

    飞行器 Crazyflie 2.0电路图/PCB布局/固件源码官方开源-电路方案

    对于有兴趣进行更高级开发的人来说,有一个开发适配器套件,支持与Crazyflie 2.0上的两个MCU轻松连接JTAG / SWD。 固件和软件不断更新,增加了各种改进和新功能。该平台通过无线电和蓝牙LE支持无线固件更新,因此当...

Global site tag (gtag.js) - Google Analytics