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

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

  1. 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的类,并且重写里面的很多方法,例如

  1. class MyAdapter extends BaseAdapter
  2. {
  3. private Context context;
  4. public MyAdapter(Context context)
  5. {
  6. this.context = context;
  7. }
  8. @Override
  9. publicint getCount() {
  10. // How many items are in the data set represented by this Adapter.(在此适配器中所代表的数据集中的条目数)
  11. return0;
  12. }
  13. @Override
  14. public Object getItem(int position) {
  15. // Get the data item associated with the specified position in the data set.(获取数据集中与指定索引对应的数据项)
  16. returnnull;
  17. }
  18. @Override
  19. publiclong getItemId(int position) {
  20. // Get the row id associated with the specified position in the list.(取在列表中与指定索引对应的行id)
  21. return0;
  22. }
  23. @Override
  24. public View getView(int position, View convertView, ViewGroup parent) {
  25. // Get a View that displays the data at the specified position in the data set.
  26. returnnull;
  27. }
  28. }

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

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

  1. @Override
  2. public View getView(int position, View convertView, ViewGroup parent) {
  3. View item = mInflater.inflate(R.layout.list_item, null);
  4. ImageView img = (ImageView)item.findViewById(R.id.img)
  5. TextView title = (TextView)item.findViewById(R.id.title);
  6. TextView info = (TextView)item.findViewById(R.id.info);
  7. img.setImageResource(R.drawable.ic_launcher);
  8. title.setText("Hello");
  9. info.setText("world");
  10. return item;
  11. }

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

  1. public View getView(int position, View convertView, ViewGroup parent) {
  2. if(convertView == null)
  3. {
  4. convertView = mInflater.inflate(R.layout.list_item, null);
  5. }
  6. ImageView img = (ImageView)convertView.findViewById(R.id.img)
  7. TextView title = (TextView)convertView.findViewById(R.id.title);
  8. TextView info = (TextView)ConvertView.findViewById(R.id.info);
  9. img.setImageResource(R.drawable.ic_launcher);
  10. title.setText("Hello");
  11. info.setText("world");
  12. return convertView;
  13. }

第三种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。

  1. //在外面先定义,ViewHolder静态类
  2. staticclass ViewHolder
  3. {
  4. public ImageView img;
  5. public TextView title;
  6. public TextView info;
  7. }
  8. //然后重写getView
  9. @Override
  10. public View getView(int position, View convertView, ViewGroup parent) {
  11. ViewHolder holder;
  12. if(convertView == null)
  13. {
  14. holder = new ViewHolder();
  15. convertView = mInflater.inflate(R.layout.list_item, null);
  16. holder.img = (ImageView)item.findViewById(R.id.img)
  17. holder.title = (TextView)item.findViewById(R.id.title);
  18. holder.info = (TextView)item.findViewById(R.id.info);
  19. convertView.setTag(holder);
  20. }else
  21. {
  22. holder = (ViewHolder)convertView.getTag();
  23. holder.img.setImageResource(R.drawable.ic_launcher);
  24. holder.title.setText("Hello");
  25. holder.info.setText("World");
  26. }
  27. return convertView;
  28. }

到这里,可能会有人问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

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical">
  6. <ListView
  7. android:id="@+id/lv"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:fastScrollEnabled="true"
  11. />
  12. </LinearLayout>

list_item.xml

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal">
  6. <ImageView
  7. android:id="@+id/img"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. />
  11. <LinearLayout
  12. android:layout_width="fill_parent"
  13. android:layout_height="wrap_content"
  14. android:orientation="vertical"
  15. >
  16. <TextView
  17. android:id="@+id/tv"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:textSize="20sp"
  21. />
  22. <TextView
  23. android:id="@+id/info"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:textSize="14sp"
  27. />
  28. </LinearLayout>
  29. </LinearLayout>

Activity

  1. package com.loulijun.demo17;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import android.app.Activity;
  9. import android.content.Context;
  10. import android.os.Bundle;
  11. import android.view.LayoutInflater;
  12. import android.view.View;
  13. import android.view.ViewGroup;
  14. import android.widget.BaseAdapter;
  15. import android.widget.ImageView;
  16. import android.widget.ListView;
  17. import android.widget.TextView;
  18.  
  19. public class Demo17Activity extends Activity {
  20. private ListView lv;
  21. private List<Map<String, Object>> data;
  22. @Override
  23. public void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.main);
  26. lv = (ListView)findViewById(R.id.lv);
  27. //获取将要绑定的数据设置到data中
  28. data = getData();
  29. MyAdapter adapter = new MyAdapter(this);
  30. lv.setAdapter(adapter);
  31. }
  32.  
  33. private List<Map<String, Object>> getData()
  34. {
  35. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  36. Map<String, Object> map;
  37. for(int i=0;i<10;i++)
  38. {
  39. map = new HashMap<String, Object>();
  40. map.put("img", R.drawable.ic_launcher);
  41. map.put("title", "跆拳道");
  42. map.put("info", "快乐源于生活...");
  43. list.add(map);
  44. }
  45. return list;
  46. }
  47.  
  48. //ViewHolder静态类
  49. static class ViewHolder
  50. {
  51. public ImageView img;
  52. public TextView title;
  53. public TextView info;
  54. }
  55.  
  56. public class MyAdapter extends BaseAdapter
  57. {
  58. private LayoutInflater mInflater = null;
  59. private MyAdapter(Context context)
  60. {
  61. //根据context上下文加载布局,这里的是Demo17Activity本身,即this
  62. this.mInflater = LayoutInflater.from(context);
  63. }
  64.  
  65. @Override
  66. public int getCount() {
  67. //How many items are in the data set represented by this Adapter.
  68. //在此适配器中所代表的数据集中的条目数
  69. return data.size();
  70. }
  71.  
  72. @Override
  73. public Object getItem(int position) {
  74. // Get the data item associated with the specified position in the data set.
  75. //获取数据集中与指定索引对应的数据项
  76. return position;
  77. }
  78.  
  79. @Override
  80. public long getItemId(int position) {
  81. //Get the row id associated with the specified position in the list.
  82. //获取在列表中与指定索引对应的行id
  83. return position;
  84. }
  85.  
  86. //Get a View that displays the data at the specified position in the data set.
  87. //获取一个在数据集中指定索引的视图来显示数据
  88. @Override
  89. public View getView(int position, View convertView, ViewGroup parent) {
  90. ViewHolder holder = null;
  91. //如果缓存convertView为空,则需要创建View
  92. if(convertView == null)
  93. {
  94. holder = new ViewHolder();
  95. //根据自定义的Item布局加载布局
  96. convertView = mInflater.inflate(R.layout.list_item, null);
  97. holder.img = (ImageView)convertView.findViewById(R.id.img);
  98. holder.title = (TextView)convertView.findViewById(R.id.tv);
  99. holder.info = (TextView)convertView.findViewById(R.id.info);
  100. //将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
  101. convertView.setTag(holder);
  102. }else
  103. {
  104. holder = (ViewHolder)convertView.getTag();
  105. }
  106. holder.img.setBackgroundResource((Integer)data.get(position).get("img"));
  107. holder.title.setText((String)data.get(position).get("title"));
  108. holder.info.setText((String)data.get(position).get("info"));
  109.  
  110. return convertView;
  111. }
  112.  
  113. }
  114. }

运行结果如下:

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. 响应式Web初级入门

    本文来自我的前端博客,原文地址:http://www.hacke2.cn/about-responsive/ 跨终端时代的到来 当你乘坐各种交通工具(公交.地铁.轻轨.火车)时你会发现,人们都个个低下 ...

  2. iOS创建子工程

    实际开发中,我们可能会同时开发好几个端,比如楼主目前开发的家教平台,需要老师端,家长端,助教端三个端.有很多工具方法,或者封装的自定义控件都是可以复用的.我们就可以把公用的代码抽取出去,新建一个工程, ...

  3. [BZOJ2656][codevs1207][Zjoi2012]数列(sequence)

    [BZOJ2656][codevs1207][Zjoi2012]数列(sequence) 试题描述 小白和小蓝在一起上数学课,下课后老师留了一道作业,求下面这个数列的通项公式: 小白作为一个数学爱好者 ...

  4. OOP感想

    OOP是面向对象编程(Object Oriented Programming).集于一身,最终目的是各司其职,让每个职责的只关注自己那块,其他的不管丢给下一个人.比如说,一个页面,对于客户,只要能看到 ...

  5. 极客DIY:制作一个可以面部、自主规划路径及语音识别的无人机

    引言 现在大部分无人机厂商都会为第三方开发者提供无人机API接口,让他们更容易地开发无人机飞行控制应用程序,让无人机想怎么玩就怎么玩.有的API接口可以帮助开发者开发基于Web版的APP.手机APP甚 ...

  6. 38 网络相关函数(六)——live555源码阅读(四)网络

    38 网络相关函数(六)——live555源码阅读(四)网络 38 网络相关函数(六)——live555源码阅读(四)网络 简介 12)makeSocketNonBlocking和makeSocket ...

  7. 32 GroupSock(AddressPortLookupTable)——live555源码阅读(四)网络

    32 GroupSock(AddressPortLookupTable)——live555源码阅读(四)网络 32 GroupSock(AddressPortLookupTable)——live555 ...

  8. func_num_args, func_get_arg, func_get-args 的区别与用法

    func_num_args 返回传递给函数的参数个数 <?php header("Content-Type: text/html; charset=UTF-8"); func ...

  9. 怎样搭建PHP开发环境

    搭建PHP开发环境首先第一步要 下载开发环境 wampserver 下载sublime text 2 sublime使用技巧 1:安装漂亮的编程字体http://pan.baidu.com/s/1xM ...

  10. 阿里云ecs云服务器安装wdcp控制面板教程

    以前就听说服务器非常的难,而且我也不懂代码,不懂英文,我怕自己学不会就买了一个月的.开始我都不知道啥样的服务器,还是我的一位哥们给我远程买的,他说这个镜像最稳定了. 服务器买好后我便开始研究,可是怎么 ...