摘要:基于Android应用程序的开发,系统界面不仅形式多样,内容上也越来越丰富,这些特点都得利于适配器的使用。BaseAdapter最大的特点是灵活而优雅,开发人员可以轻松的构造BaseAdapter并将其搭载到所需的控件中去,从而使系统呈现不同的效果。该文从BaseAdapter的构造过程阐述了适配器的原理并通过程序实现适配器搭载不同UI界面控件的过程。
关键词:Android;BaseAdapter;适配器
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)26-0085-03
Based on BaseAdapter Adapter to Understand in the Android
OU Chu-xiang
(Guangzhou Railway Polytechnic, Guangzhou 510430, China)
Abstract: Application development based-on Android not only presented in various forms, also enriched in its contents, all this can contributed to the use of an adapter. The most important feature of BsedAdapter is flexible and elegant, which can be easily constructed and implied to the needed controlers thus making a various appearing effect by the developers. The theory of construction of BaseAdapter and the programmed process of different UI interface controllers equipped with the adapter is proposed in this paper.
Key words: Android; BaseAdapter; the adapter
1 概述
在Android软件开发学习中,适配器模式(Adapter Pattern)是必须学习的。GOF(Gang of four)的《Design Pattern》中设配器模式定义:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法再一起工作的两个类能够在一起工作[1]。理解这段定义,我们可以从手机充电方面去理解。手机充电器可以看作一个适配器,而220V交流电电源是一个类,手机是另一个类,手机需要的电压是5.0V电压,所以在充电时需要一个变压器(充电器)将220V电压转换成手机所需的5.0V电压,这正像是适配器所做的事。
BaseAdapter在Android引用程序中应用非常广泛,它是一个基础数据适配器,其用途是将一组杂乱的数据按照一定的规则应用到ListView、Spinner、Gallery和GridView等UI界面组件中。也就是说,Adapter可以看作数据源和UI界面组件之间数据沟通的桥梁,如图1所示:
图 1
2 对原生Adapter的理解
在开发过程中,程序员会经常使用Adapter,因此谷歌公司给Android定义了一些原生的Adapter。这些原生的Adapter不仅负责提供数据,而且还负责创建每一个条目的视图,所以我们可以轻松的引用这些Adapter。原生的Adapter最有用、最常用的主要有以下两个:
1)ArrayAdapter类
ArrayAdapter类继承了BaseAdapter类,利用JAVA泛型来定义绑定的数据类型对象,从而从数据类型对象的toString方法获得相应的值,用来创建和填充文本视图。
2)SimpleCursorAdapter类
SimpleCursorAdapter类的基类同样也是BaseAdapter类,它可以把一个布局中的视图和(通常从Content Provider 查询返回的)游标的特定列绑定在一起[2]。
3 创建一个自己的适配器
既然前面讲的ArrayAdapter类和SimpleCursorAdapter类的基类是BaseAdapter类,那么我们就可以依照这两个类来编写自己的Adapter。在继承BaseAdapter类之后,我们需要实现getCount()、getItem()、getItemId()和getView()几个方法。其中getCount()返回列表项的长度;getItem()返回指定列表项数据;getItemId()返回指定列表项在列表中的位置;getView()返回指定的列表视图。具体代码如下:
public class StructureAdapter extends BaseAdapter
{
//初始化数据
private List
private Context mContext;
private LayoutInflater mInflater;
public StructureAdapter(List
{
客服热线:400-656-5456 客服专线:010-56265043 电子邮箱:longyuankf@126.com
电信与信息服务业务经营许可证:京icp证060024号
Dragonsource.com Inc. All Rights Reserved
super();
this.mList = list;
this.mContext = context;
//获取到当前视图压力泵
mInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount()
{
return mList.size();
}
@Override
public Object getItem(int position)
{
return mList.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return mInflater.inflate(resource, null);
}
}
在这里,我们应该重点去完成getView()的代码实现,在实现代码前,还需要去创建一个XML的试图文件和一个数据类型对象模型的Java文件,XML也就是代码中resource。这里创建一个简单的视图文件Item.xml,视图中有一个ImageView和两个TextView,布局如图2:
图 2
数据类型对象模型的Java文件可以创建一个ItemModel.java文件,代码如下:
public class ItemModel
{
public int ItemImageResId;
public String ItemTitle;
public String ItemContent;
public ItemModel (int itemImageResId, String itemTitle, String itemContent)
{
super();
ItemImageResId = itemImageResId;
ItemTitle = itemTitle;
ItemContent = itemContent;
}
}
1)简单实现视图代码
在实现getView()里面代码时,我们不考虑其他情况的前提下,可以这样实现代码:
public View getView(int position, View convertView, ViewGroup parent)
{
View view = mInflater.inflate(R.layout.item, null);
ImageView imageView = (ImageView) view .findViewById(R.id.iv_image);
TextView title = (TextView)view.findViewById(R.id.tv_title);
TextView content = (TextView)view.findViewById(R.id.tv_content);
ItemModel model= mList.get(position);
imageView.setImageResource(model.ItemImageResId);
title.setText(model.ItemTitle);
content.setText(model.ItemContent);
return view;
}
这种实现方式可以清晰的表述出适配器所绑定的视图,利于初学者理解Adapter原理。但这种方式也有其弊端,因为它没有充分考虑到Android所运行的性能环境,Android所运行的环境中硬件资源是有限的,像上述代码在运行时会重复创建视图资源,消耗大量的内存资源。因此,我们必须优化代码,减少资源的消耗。其实在Android中有一个Recycler构
建,可以帮助优化代码。我们结合getView()方法来看Recycler的工作原理[3],如图3:
图3
从图3中可以看出,Recycler构建就是在滑动屏幕后,当Item1滑动出屏幕,将其重新构建视图及赋值产生出Item8,达到重复利用的效果,减少硬件资源的消耗。
2)优化视图实现代码
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
//view未被实例化,缓存池中没有view的缓存,所以需要新建
convertView = mInflater.inflate(R.layout.item, null);
}
ImageView imageView = (ImageView) convertView .findViewById(R.id.iv_image);
TextView title = (TextView)convertView.findViewById(R.id.tv_title);
TextView content = (TextView)convertView.findViewById(R.id.tv_content);
ItemModel model= mList.get(position);
imageView.setImageResource(model.ItemImageResId);
title.setText(model.ItemTitle);
content.setText(model.ItemContent);
return convertView;
}
代码实现虽然只多写一段条件判断代码,但这段代码才是整个getView()方法的核心。在条件判断为真的时候,内部去创建视图,避免视图的重复被创建。
以上代码在Eclipse、Android SDK4.1环境下开发,在SDK4.3、SDK5.1等调试通过。
4 结束语
设计Adapter时需要有代码重构的思想,这也符合面向对象程序设计思想,针对特有的接口设计Adapter可以解决数据与UI界面组件不匹配的情况。在设计时也需要考虑资源的消耗问题,优化我们的Adapter。
参考文献:
[1] GOF. Design Patterns: Elements of Reusable Object-Oriented Software[M]. Pearson Education,2000:95-96.
[2] Reto Meier.Android 4 高级编程[M].3版.北京:清华大学出版社,2013:138.
[3] Satya Komatineni,Dave MacLean.精通Android[M]. 北京:人民邮电出版社,2013:127-131.