话说开发用了各种Adapter之后感觉用的最舒服的还是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView、GridView、Gallery、Spinner等等。它是直接继承自接口类Adapter的,使用BaseAdapter时需要重写很多方法,其中最重要的当属getView,因为这会涉及到ListView优化等问题,其他的方法可以参考链接的文章

BaseAdapter与其他Adapter有些不一样,其他的Adapter可以直接在其构造方法中进行数据的设置,比如

 SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.list_item, new String[]{"img","title","info",newint[]{R.id.img, R.id.title, R.id.info}});  

但是在BaseAdapter中需要实现一个继承自BaseAdapter的类,并且重写里面的很多方法,例如

 class MyAdapter extends BaseAdapter
{
private Context context;
public MyAdapter(Context context)
{
this.context = context;
}
@Override
publicint getCount() {
// How many items are in the data set represented by this Adapter.(在此适配器中所代表的数据集中的条目数)
return0;
}
@Override
public Object getItem(int position) {
// Get the data item associated with the specified position in the data set.(获取数据集中与指定索引对应的数据项)
returnnull;
}
@Override
publiclong getItemId(int position) {
// Get the row id associated with the specified position in the list.(取在列表中与指定索引对应的行id)
return0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get a View that displays the data at the specified position in the data set.
returnnull;
}
}

这里面没什么难度,但是这个getView方法必须好好处理,也是最麻烦的

第一种:没有任何处理,不建议这样写。如果数据量少看将就,但是如果列表项数据量很大的时候,会每次都重新创建View,设置资源,严重影响性能,所以从一开始就不要用这种方式

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
View item = mInflater.inflate(R.layout.list_item, null);
ImageView img = (ImageView)item.findViewById(R.id.img)
TextView title = (TextView)item.findViewById(R.id.title);
TextView info = (TextView)item.findViewById(R.id.info);
img.setImageResource(R.drawable.ic_launcher);
title.setText("Hello");
info.setText("world");
return item;
}

第二种ListView优化:通过缓存convertView,这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能

 public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = mInflater.inflate(R.layout.list_item, null);
}
ImageView img = (ImageView)convertView.findViewById(R.id.img)
TextView title = (TextView)convertView.findViewById(R.id.title);
TextView info = (TextView)ConvertView.findViewById(R.id.info);
img.setImageResource(R.drawable.ic_launcher);
title.setText("Hello");
info.setText("world");
return convertView;
}

第三种ListView优化:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,使用 ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。

当我们判断 convertView == null  的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。(看下面代码中)

如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。

 //在外面先定义,ViewHolder静态类
staticclass ViewHolder
{
public ImageView img;
public TextView title;
public TextView info;
}
//然后重写getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item, null);
holder.img = (ImageView)item.findViewById(R.id.img)
holder.title = (TextView)item.findViewById(R.id.title);
holder.info = (TextView)item.findViewById(R.id.info);
convertView.setTag(holder);
}else
{
holder = (ViewHolder)convertView.getTag();
holder.img.setImageResource(R.drawable.ic_launcher);
holder.title.setText("Hello");
holder.info.setText("World");
}
return convertView;
}

到这里,可能会有人问ViewHolder静态类结合缓存convertView与直接使用convertView有什么区别吗,是否重复了

在这里,官方给出了解释

提升Adapter的两种方法

To work efficiently the adapter implemented here uses two techniques: -It reuses the convertView passed to getView() to avoid inflating View when it is not necessary

(译:重用缓存convertView传递给getView()方法来避免填充不必要的视图) -It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary

(译:使用ViewHolder模式来避免没有必要的调用findViewById():因为太多的findViewById也会影响性能) ViewHolder类的作用 -The ViewHolder pattern consists in storing a data structure in the tag of the view returned by getView().This data structures contains references to the views we want to bind data to, thus avoiding calling to findViewById() every time getView() is invoked

(译:ViewHolder模式通过getView()方法返回的视图的标签(Tag)中存储一个数据结构,这个数据结构包含了指向我们

要绑定数据的视图的引用,从而避免每次调用getView()的时候调用findViewById())

实例一:用BaseAdapter来自定义ListView布局

main.xml

 <?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/lv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fastScrollEnabled="true"
/>
</LinearLayout>

list_item.xml

 <?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
/>
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
/>
</LinearLayout>
</LinearLayout>

Activity

 package com.loulijun.demo17;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView; public class Demo17Activity extends Activity {
private ListView lv;
private List<Map<String, Object>> data;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView)findViewById(R.id.lv);
//获取将要绑定的数据设置到data中
data = getData();
MyAdapter adapter = new MyAdapter(this);
lv.setAdapter(adapter);
} private List<Map<String, Object>> getData()
{
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map;
for(int i=0;i<10;i++)
{
map = new HashMap<String, Object>();
map.put("img", R.drawable.ic_launcher);
map.put("title", "跆拳道");
map.put("info", "快乐源于生活...");
list.add(map);
}
return list;
} //ViewHolder静态类
static class ViewHolder
{
public ImageView img;
public TextView title;
public TextView info;
} public class MyAdapter extends BaseAdapter
{
private LayoutInflater mInflater = null;
private MyAdapter(Context context)
{
//根据context上下文加载布局,这里的是Demo17Activity本身,即this
this.mInflater = LayoutInflater.from(context);
} @Override
public int getCount() {
//How many items are in the data set represented by this Adapter.
//在此适配器中所代表的数据集中的条目数
return data.size();
} @Override
public Object getItem(int position) {
// Get the data item associated with the specified position in the data set.
//获取数据集中与指定索引对应的数据项
return position;
} @Override
public long getItemId(int position) {
//Get the row id associated with the specified position in the list.
//获取在列表中与指定索引对应的行id
return position;
} //Get a View that displays the data at the specified position in the data set.
//获取一个在数据集中指定索引的视图来显示数据
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
//如果缓存convertView为空,则需要创建View
if(convertView == null)
{
holder = new ViewHolder();
//根据自定义的Item布局加载布局
convertView = mInflater.inflate(R.layout.list_item, null);
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.title = (TextView)convertView.findViewById(R.id.tv);
holder.info = (TextView)convertView.findViewById(R.id.info);
//将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
convertView.setTag(holder);
}else
{
holder = (ViewHolder)convertView.getTag();
}
holder.img.setBackgroundResource((Integer)data.get(position).get("img"));
holder.title.setText((String)data.get(position).get("title"));
holder.info.setText((String)data.get(position).get("info")); return convertView;
} }
}

运行结果如下:

ListView之BaseAdapter的使用的更多相关文章

  1. 第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter

    第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter 1.BaseAdapter BaseAdapter是Android应用程序中经常用到的基础数据适配器,它的 ...

  2. ListView之BaseAdapter

    BaseAdapter可以实现自定义的丰富子项视图,本文实现如下所示结果: 实现代码: /* ListView :列表 BaseAdapter 通用的基础适配器 * * */ public class ...

  3. Android 杂谈---ListView 之BaseAdapter

    前言 几种适配器里面相对来说比较简单的一种适配器,在使用时需要实现几个方法,并且也需要对convertView进行优化 此篇文章以使用listView与BaseAdapter来实现表格样式的布局举例( ...

  4. andorid 列表视图 ListView 之BaseAdapter

    .xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android=&qu ...

  5. Android关于listView的BaseAdapter以及getView的三级优化

    1.4个重写方法的含义 自定义Adapter继承自BaseAdapter(通用适配器)   getCount(); getItem(); getItemId(); getViewTypaCount() ...

  6. android 中listview之BaseAdapter的使用

    Listview控件不像其他安卓控件那种直接拖拽到界面上就能用,而是采用类似J2EE中的MVC模型的方式使用,需要通过适配器将某种样式的数据或控件添加到其上而使用. MVC模型实现原理是 数据模型M( ...

  7. android ListView 和 BaseAdapter 应用

    步聚: 1.建立ListView对象:--(作用:绑定Adapter呈现数据) 2.建立ListView实现的Item栏位.xml布局:--(作用:实现ListView的栏位布局) 3.建立Item. ...

  8. 43.Android之ListView中BaseAdapter学习

    实际开发中个人觉得用的比较多是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView.GridView.Gallery.Spinner ...

  9. ListView配合BaseAdapter

    BaseAdapter使用比较麻烦,它是个抽象类,需要重写4个方法分别是getCount() getItem(..) getItemId(..) getVew(..),相应的使用BaseAdapter ...

随机推荐

  1. [原] Android性能优化方法

    GPU过度绘制 打开开发者选型,"调试GPU过度绘制",蓝.绿.粉红.红,过度绘制依次加深 粉红色尽量优化,界面尽量保持蓝绿颜色 红色肯定是有问题的,不能忍受 使用Hierarch ...

  2. [译]git remote

    git remote命令让我们可以创建, 查看, 删除一个到其他仓储的连结. 下图展示了我们的本地仓储有两个remote连接, 一个是中央仓储, 一个是其他开发者的仓储. 除了使用完整的url指向他们 ...

  3. windows2003最详细的安装操作步骤.(最详细)

    以下为windows2003的安装操作步骤,由于安装操作步骤较多,安装可能需要一定的实际安装经验.安装时请参照此文档一步步完成安装. 一.首先准备好Windows2003安装光盘CD1,将CD1光盘放 ...

  4. 滑雪 why WA

    滑雪 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 587  Solved: 219 Description 小明喜欢滑雪,因为滑雪的确很刺激,可是为了获 ...

  5. 【C语言入门教程】1.2 函数库 和 链接

    程序员可以不需要从头开始设计每一个函数,完成用C语言命令所实现的函数非常罕见.因为所有的C语言编辑器都提供能完成各种常见任务函数,如printf()函数等.C语言编译器的实现者已经编写了大部分常见的通 ...

  6. 比较两个数据库表table结构不同之处

    /*--比较两个数据库的表字段差异 hy 适用多种版本库 --*/ /*--调用示例 exec p_comparestructure 'database1','database2' --*/ ) dr ...

  7. html5 图片转为base64格式异步上传

    因为有这个需求(移动端),所以就研究了一下,发现还挺不错的.这个主要是用了html5的API,不需要其他的JS插件,不过只有支持html5的浏览器才行,就现在而言应该大部份都支持的.<!DOCT ...

  8. iOS软件版本更新思路

    iOS软件更新思路 需要更新版本数组 needUpdateVersions{1.2.61.2.8} 历史版本数组 historyUpdateVersions1.2.41.2.51.2.6 更新数据库1 ...

  9. ios中常见数据存储方式以及SQLite常用的语句

    在iOS中,根据不同的需求对应的有多种数据存储方式: 1.NSUserdefaults  将数据存储到沙盒中(library),方便易用,但是只能存储系统提供的数据类型(plist),不能存储自定义的 ...

  10. 剑指Offer 包含min函数的栈

    题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数.   思路: 这个题是想得到一个时间复杂度为O(1)的min函数,所以应用一个辅助栈,压的时候,如果A栈的压入比B栈压入 ...