首页 > 代码库 > 【转】Android之自定义Adapter的ListView

【转】Android之自定义Adapter的ListView

http://www.cnblogs.com/topcoderliu/archive/2011/05/07/2039862.html 

 

 

在开发中,我们经常使用到ListView这个控件。Android的API也提供了许多创建ListView适配器的快捷方式。例如ArrayAdapter、SimpleAdapter和SimpleCursorAdapter等。但你是否发现,如果采用这些系统自带的适配器,对于事件的响应只能局限在一个行单位。假设一行里面有一个按钮和一个图片控件,它们之间的响应操作是不一样的。若采用系统自带的适配器,就不能精确到每个控件的响应事件。这时,我们一般采取自定义适配器来实现这个比较精确地请求。

 

       ListView的创建,一般要具备两大元素:

       1)数据集,即要映射的字符串、图片信息之类。

       2)适配器,实现把要映射的字符串、图片信息映射成视图(如Textview、Image等组件),再添加到ListView中。

       下面是一个实操例子:

       实现细节:

       1、创建数据集,一般定义如下

        private List<Map<String, Object>> listItems;

        元素添加方式:

        Map<String, Object> map = new HashMap<String, Object>(); 
        map.put("image", imgeIDs[i]);          //图片资源
        map.put("title", "物品名称:");           //物品标题
        map.put("info", goodsNames[i]);      //物品名称
        map.put("detail", goodsDetails[i]);   //物品详情
        listItems.add(map);                         //添加一项

        2、创建适配器

        public class ListViewAdapter extends BaseAdapter{........}  //自定义的适配器一般继承BaseAdapter类

        listViewAdapter = new ListViewAdapter(this, listItems);

        3、给ListView设置适配器

        listView.setAdapter(listViewAdapter);

        4、这里还有个关键点,如何把list_item.xml布局作为一个视图,添加到listView中:

        LayoutInflater listContainer;   //视图容器工厂

        listContainer = LayoutInflater.from(context); //创建视图容器工厂并设置上下文

        convertView = listContainer.inflate(R.layout.list_item, null);   //创建list_item.xml布局文件的视图

       

        实例视图如下:

1)布局文件main.xml       

  1. <?xml version="1.0" encoding="utf-8"?>  
  2.  <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"  
  3.     Android:orientation="vertical"  
  4.     Android:layout_width="fill_parent"  
  5.     Android:layout_height="fill_parent">  
  6.        
  7.     <!-- 结算 -->  
  8.     <LinearLayout Android:gravity="center_horizontal"  
  9.     Android:orientation="horizontal" android:layout_width="fill_parent"  
  10.     Android:layout_height="wrap_content">  
  11.     <TextView Android:text="结算: "  
  12.         Android:layout_width="wrap_content"  
  13.         Android:layout_height="wrap_content"    
  14.         Android:textColor="#FFFFFFFF"    
  15.         Android:textSize="20px"/>  
  16.     <ImageButton Android:id="@+id/imgbt_sum"    
  17.         Android:layout_width="40px"  
  18.         Android:layout_height="40px"  
  19.         Android:background = "@drawable/shopping" />  
  20.     </LinearLayout>  
  21.        
  22.     <TextView Android:text="商品列表: "  
  23.         Android:layout_width="wrap_content"  
  24.         Android:layout_height="wrap_content"    
  25.         Android:textColor="#FFFFFFFF" />  
  26.            
  27.     <!-- 商品列表 -->    
  28.     <ListView Android:id="@+id/list_goods"    
  29.         Android:layout_width="fill_parent"  
  30.         Android:layout_height="wrap_content" />  
  31.            
  32.  </LinearLayout>  

       列表项布局文件list_item.xml      

  1. <?xml version="1.0" encoding="utf-8"?>  
  2.  <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"  
  3.     Android:orientation="horizontal" android:layout_width="fill_parent"  
  4.     Android:layout_height="fill_parent">  
  5.   
  6.     <!-- 商品图片 -->  
  7.     <ImageView Android:id="@+id/imageItem"    
  8.         Android:layout_width="wrap_content"  
  9.         Android:layout_height="wrap_content"    
  10.         Android:layout_margin="5px"/>  
  11.        
  12.     <!-- 商品信息 -->  
  13.     <LinearLayout Android:orientation="vertical"  
  14.         Android:layout_width="wrap_content"    
  15.         Android:layout_height="wrap_content">  
  16.   
  17.         <TextView Android:id="@+id/titleItem"    
  18.             Android:layout_width="wrap_content"  
  19.             Android:layout_height="wrap_content"    
  20.             Android:textColor="#FFFFFFFF"  
  21.             Android:textSize="13px" />  
  22.         <TextView Android:id="@+id/infoItem"    
  23.             Android:layout_width="wrap_content"  
  24.             Android:layout_height="wrap_content"    
  25.             Android:textColor="#FFFFFFFF"  
  26.             Android:textSize="22px" />  
  27.     </LinearLayout>  
  28.        
  29.     <!-- 购买和商品详情 -->  
  30.     <LinearLayout Android:gravity="right"  
  31.     Android:orientation="horizontal" android:layout_width="fill_parent"  
  32.     Android:layout_height="wrap_content">  
  33.     <CheckBox Android:id="@+id/checkItem"    
  34.         Android:layout_width="wrap_content"  
  35.         Android:layout_height="wrap_content"    
  36.         Android:layout_margin="5px"/>  
  37.     <Button  Android:id="@+id/detailItem"    
  38.         Android:layout_width="wrap_content"  
  39.         Android:layout_height="wrap_content"    
  40.         Android:layout_margin="5px"/>  
  41.     </LinearLayout>  
  42.  </LinearLayout>  

        2)代码,主代码:        

  1. package com.myAndroid.test;   
  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.app.AlertDialog;   
  10. import Android.content.DialogInterface;   
  11. import Android.os.Bundle;   
  12. import Android.view.View;   
  13. import Android.view.View.OnClickListener;   
  14. import Android.widget.ArrayAdapter;   
  15. import Android.widget.ImageButton;   
  16. import Android.widget.ListView;   
  17.   
  18. public class MyListView extends Activity {   
  19.        
  20.     private ListView listView;   
  21.     private ImageButton imgbt_sum;   
  22.     private ListViewAdapter listViewAdapter;   
  23.     private List<Map<String, Object>> listItems;   
  24.     private Integer[] imgeIDs = {R.drawable.cake,    
  25.             R.drawable.gift, R.drawable.letter,   
  26.             R.drawable.love, R.drawable.mouse,   
  27.             R.drawable.music};   
  28.     private String[] goodsNames = {"蛋糕", "礼物",    
  29.             "邮票", "爱心", "鼠标", "音乐CD"};   
  30.     private String[] goodsDetails = {   
  31.             "蛋糕:好好吃。",    
  32.             "礼物:礼轻情重。",    
  33.             "邮票:环游世界。",    
  34.             "爱心:世界都有爱。",   
  35.             "鼠标:反应敏捷。",   
  36.             "音乐CD:酷我音乐。"};   
  37.        
  38.     /** Called when the activity is first created. */  
  39.     @Override  
  40.     public void onCreate(Bundle savedInstanceState) {   
  41.         super.onCreate(savedInstanceState);   
  42.         setContentView(R.layout.main);   
  43.            
  44.         listView = (ListView)findViewById(R.id.list_goods);    
  45.         imgbt_sum = (ImageButton) findViewById(R.id.imgbt_sum);   
  46.         imgbt_sum.setOnClickListener(new ClickEvent());   
  47.         listItems = getListItems();   
  48.         listViewAdapter = new ListViewAdapter(this, listItems); //创建适配器   
  49.         listView.setAdapter(listViewAdapter);   
  50.     }   
  51.        
  52.     /**  
  53.      * 初始化商品信息  
  54.      */  
  55.     private List<Map<String, Object>> getListItems() {   
  56.         List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();   
  57.         for(int i = 0; i < goodsNames.length; i++) {   
  58.             Map<String, Object> map = new HashMap<String, Object>();    
  59.             map.put("image", imgeIDs[i]);               //图片资源   
  60.             map.put("title", "物品名称:");              //物品标题   
  61.             map.put("info", goodsNames[i]);     //物品名称   
  62.             map.put("detail", goodsDetails[i]); //物品详情   
  63.             listItems.add(map);   
  64.         }      
  65.         return listItems;   
  66.     }   
  67.        
  68.     class ClickEvent implements OnClickListener{   
  69.   
  70.         @Override  
  71.         public void onClick(View v) {   
  72.             // TODO Auto-generated method stub   
  73.             String goodsList = "";   
  74.             for(int i = 0; i < listItems.size(); i++) {   
  75.                 goodsList += listViewAdapter.hasChecked(i)? goodsNames[i] + "  ": "";   
  76.             }   
  77.             new AlertDialog.Builder(MyListView.this)   
  78.             .setTitle("购物清单:")   
  79.             .setMessage("你好,你选择了如下商品:\n" + goodsList)   
  80.             .setPositiveButton("确定", null)   
  81.             .show();   
  82.         }   
  83.            
  84.     }   
  85. }   

 

 

适配器代码:      

  1. package com.myAndroid.test;   
  2.   
  3.  import java.util.List;   
  4. import java.util.Map;   
  5.   
  6. import Android.app.AlertDialog;   
  7. import Android.content.Context;   
  8. import Android.util.Log;   
  9. import Android.view.LayoutInflater;   
  10. import Android.view.View;   
  11. import Android.view.ViewGroup;   
  12. import Android.widget.BaseAdapter;   
  13. import Android.widget.Button;   
  14. import Android.widget.CheckBox;   
  15. import Android.widget.CompoundButton;   
  16. import Android.widget.ImageView;   
  17. import Android.widget.ListView;   
  18. import Android.widget.TextView;   
  19.   
  20. public class ListViewAdapter extends BaseAdapter {   
  21.     private Context context;                        //运行上下文   
  22.     private List<Map<String, Object>> listItems;    //商品信息集合   
  23.     private LayoutInflater listContainer;           //视图容器   
  24.     private boolean[] hasChecked;                   //记录商品选中状态   
  25.     public final class ListItemView{                //自定义控件集合     
  26.             public ImageView image;     
  27.             public TextView title;     
  28.             public TextView info;   
  29.             public CheckBox check;   
  30.             public Button detail;          
  31.      }     
  32.        
  33.        
  34.     public ListViewAdapter(Context context, List<Map<String, Object>> listItems) {   
  35.         this.context = context;            
  36.         listContainer = LayoutInflater.from(context);   //创建视图容器并设置上下文   
  37.         this.listItems = listItems;   
  38.         hasChecked = new boolean[getCount()];   
  39.     }   
  40.   
  41.     public int getCount() {   
  42.         // TODO Auto-generated method stub   
  43.         return listItems.size();   
  44.     }   
  45.   
  46.     public Object getItem(int arg0) {   
  47.         // TODO Auto-generated method stub   
  48.         return null;   
  49.     }   
  50.   
  51.     public long getItemId(int arg0) {   
  52.         // TODO Auto-generated method stub   
  53.         return 0;   
  54.     }   
  55.        
  56.     /**  
  57.      * 记录勾选了哪个物品  
  58.      * @param checkedID 选中的物品序号  
  59.      */  
  60.     private void checkedChange(int checkedID) {   
  61.         hasChecked[checkedID] = !hasChecked[checkedID];   
  62.     }   
  63.        
  64.     /**  
  65.      * 判断物品是否选择  
  66.      * @param checkedID 物品序号  
  67.      * @return 返回是否选中状态  
  68.      */  
  69.     public boolean hasChecked(int checkedID) {   
  70.         return hasChecked[checkedID];   
  71.     }   
  72.        
  73.     /**  
  74.      * 显示物品详情  
  75.      * @param clickID  
  76.      */  
  77.     private void showDetailInfo(int clickID) {   
  78.         new AlertDialog.Builder(context)   
  79.         .setTitle("物品详情:" + listItems.get(clickID).get("info"))   
  80.         .setMessage(listItems.get(clickID).get("detail").toString())                 
  81.         .setPositiveButton("确定", null)   
  82.         .show();   
  83.     }   
  84.        
  85.           
  86.     /**  
  87.      * ListView Item设置  
  88.      */  
  89.     public View getView(int position, View convertView, ViewGroup parent) {   
  90.         // TODO Auto-generated method stub   
  91.         Log.e("method", "getView");   
  92.         final int selectID = position;   
  93.         //自定义视图   
  94.         ListItemView  listItemView = null;   
  95.         if (convertView == null) {   
  96.             listItemView = new ListItemView();    
  97.             //获取list_item布局文件的视图   
  98.             convertView = listContainer.inflate(R.layout.list_item, null);   
  99.             //获取控件对象   
  100.             listItemView.image = (ImageView)convertView.findViewById(R.id.imageItem);   
  101.             listItemView.title = (TextView)convertView.findViewById(R.id.titleItem);   
  102.             listItemView.info = (TextView)convertView.findViewById(R.id.infoItem);   
  103.             listItemView.detail= (Button)convertView.findViewById(R.id.detailItem);   
  104.             listItemView.check = (CheckBox)convertView.findViewById(R.id.checkItem);   
  105.             //设置控件集到convertView   
  106.             convertView.setTag(listItemView);   
  107.         }else {   
  108.             listItemView = (ListItemView)convertView.getTag();   
  109.         }   
  110. //      Log.e("image", (String) listItems.get(position).get("title"));  //测试   
  111. //      Log.e("image", (String) listItems.get(position).get("info"));   
  112.            
  113.         //设置文字和图片   
  114.         listItemView.image.setBackgroundResource((Integer) listItems.get(   
  115.                 position).get("image"));   
  116.         listItemView.title.setText((String) listItems.get(position)   
  117.                 .get("title"));   
  118.         listItemView.info.setText((String) listItems.get(position).get("info"));   
  119.         listItemView.detail.setText("商品详情");   
  120.         //注册按钮点击时间爱你   
  121.         listItemView.detail.setOnClickListener(new View.OnClickListener() {   
  122.             @Override  
  123.             public void onClick(View v) {   
  124.                 //显示物品详情   
  125.                 showDetailInfo(selectID);   
  126.             }   
  127.         });   
  128.         // 注册多选框状态事件处理   
  129.         listItemView.check   
  130.                 .setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {   
  131.                     @Override  
  132.                     public void onCheckedChanged(CompoundButton buttonView,   
  133.                             boolean isChecked) {   
  134.                         //记录物品选中状态   
  135.                         checkedChange(selectID);   
  136.                     }   
  137.         });   
  138.            
  139.         return convertView;   
  140.     }   
  141. }  

        至于,如何实现系统自带的适配器,如ArrayAdapter、SimpleAdapter和SimpleCursorAdapter等,有机会再补充