自定義listview

 

   在開發中,我們經常使用到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等,有機會再補充。

 

原文鏈接:http://www.linuxidc.com/Linux/2011-05/35394.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章