[转]ListView由复杂到简单

转自http://www.cnblogs.com/carmanloneliness/archive/2012/02/27/2370597.html

ListView由复杂到简单

  项目做完了,其中用到的ListView控件很大,有自由的时间就总结一下ListView的各个知识点。谈到ListView总是离不开adapter的使用,在这片文章中也总结下adapter的使用,主要讲述两个adapter吧,baseadapter和cursoradapter的使用。这俩是使用频率最多的adapter。当然还有用系统的adapter,但这个较简单。到文章最后再举几个更复杂的ListView的例子,作为扩展内容。

  一.在xmlListView应设置为

  <ListView android:id="@+id/list_goods" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" />。主要就是宽度填满,高度自适应。

  还有很多很实用的属性:

  android:cacheColorHint="#00000000"  :ListView上下拖动的时候会出现黑框,如下图所示。设置左边的属性就可完美解决,当然在代码中也设置该属性(不推荐).

            

  android:divider="#000000"  该属性是用来设置ListView 间隔线 的颜色。很实用

  android:dividerHeight="1px" 用来设置  间隔线 的高度,要设置的话一般就是1px,能看出来颜色就OK啦。

  Android中有很多xml属性可以完美解决的事情,譬如在manifest文件的activity标签中设置android:theme="@android:style/Theme.NoTitleBar",就可隐藏标题。希望读者多研究研究这一点,最好不要在Java代码里面实现这些功能。

  二:绑定继承自BaseAdapter的的ListView

  第一次使用自定义adapter理解起来有点复杂,因为继承的方法太多,其中最主要的就是getView方法。多联系就熟悉啦。自定义adapter的目的无非以下几点:

  ListView中实现按钮的监听:

  要有漂亮图片的显示;

  复选框等复杂控件的显示;

  需求较复杂,系统自带的adapter满足不了要求。

  结合最常用的上述几点要求,弄一个综合的ListView例子来讲述下这些功能的实现。

效果如下图:

    

  这个例子里实现了图片显示,复选框,按钮。共用了五个控件,一个ImageView(imageItem),两个TextView(titleItem,infoItem),一个CheckBox(checkItem),一个Button(detailItem)。在这里详细说明下如何定义adapter,Demo的代码放在附件代码里供下载吧。

 

  public ListViewAdapter(Context context, List<Map<String, Object>> listItems) {

    this.listItems = listItems;
    XXXXXXX  
  }

  构造放在的作用是传入一个listItems,listItems是ListView容器中各个控件显示的内容,imageItem要显示的图片,titleItem和infoItem要显示的文字以及点击detailItem弹出对话所显示的文字,在定义adapter时调用构造方法将设置好的变量传入adapter当中来,这样就有内容。接下来就依次介绍下实现BaseAdapter所必须继承的方法。 

  1.@Override
  public int getCount() {
    // TODO Auto-generated method stub
    return listItems.size();
  }

  这个是ListView中所包含的Item的数量。既然数据都在listItems中,那么这里就返回listItems的长度。

  2.@Override

   public Object getItem(int position) {
    // TODO Auto-generated method stub
    return null;
   }

  这里可以return null.但更专业一点返回listItems.get(position),这样在getView函数中直接调用getItem(int XX)方法就行了,不用再调用具体的值,更好的提现了封装性;

  3.@Override

  public long getItemId(int position) {
    // TODO Auto-generated method stub
    return 0;
  }

  和2中同样的道理,可以return 0,也可以return position.

  4.这个ListView中共有5个控件,控件较多,要定义一个final类型的内部类,来封装这些控件,如下所示:

    public final class ListItemView{ //自定义控件集合 
      public ImageView image; 
      public TextView title; 
      public TextView info; 
      public CheckBox check; 
      public Button detail; 
    }这样在getView中赋值的话直接用"变量名.类的变量"就可以了。当然也可以不用声明内部类,而用变量引用来实现。

  5.最主要的就是接下来的getView方法

getView方法的参数共3个,这三个参数具体含义可查API文档,讲解的比我详细,返回值就是中间这个变量convertView,getView的方法作用简单说来就是将第二个参数赋予正确的值并且返回。这其中要注意一点要将convertView绑定4中内部类的一个变量,这才能是convertView设置为正确的格式。通过setTag的方法来实现该功能。

ListItemView listItemView = null; 
  if (convertView == null) { 
    XXXX
    convertView.setTag(listItemView);  
  }else { 
    listItemView = (ListItemView)convertView.getTag(); 
  }

  若想实现ListView的单双行不同颜色显示,或者各行不同颜色显示,就要在getView方法中实现。举例,单双行不同颜色显示的方法如下:

  if(position % 2 == 0)
    convertView.setBackgroundColor(Color.WHITE);
  else
    convertView.setBackgroundColor(Color.parseColor("#F9F6F1"));

同样的功能,若是在CursorAdapter中实现,就要在newView方法里面实现,而不是在bindView里面实现。

代码附上!太晚了,就写到baseAdapter吧,cursoradapter明天写。想得挺简单的,一提笔就觉得有很多细节要交代,各位看官将就看吧,若不明,邮件给我carman_loneliness@163.com

                

                                          -Carman

                                          -2010.2.27

 

复制代码
  1 package a.b;
  2 
  3 import java.util.List;   
  4 import java.util.Map;   
  5 import android.app.AlertDialog;   
  6 import android.content.Context;   
  7 import android.util.Log;   
  8 import android.view.LayoutInflater;   
  9 import android.view.View;   
 10 import android.view.ViewGroup;   
 11 import android.widget.BaseAdapter;   
 12 import android.widget.Button;   
 13 import android.widget.CheckBox;   
 14 import android.widget.CompoundButton;   
 15 import android.widget.ImageView;      
 16 import android.widget.TextView;
 17 
 18 public class ListViewAdapter extends BaseAdapter {
 19     
 20     private Context context;                       
 21     private List<Map<String, Object>> listItems;  
 22     private LayoutInflater listContainer;          
 23     private boolean[] hasChecked;                  
 24     public final class ListItemView{              
 25             public ImageView image;     
 26             public TextView title;     
 27             public TextView info;   
 28             public CheckBox check;   
 29             public Button detail;          
 30      }
 31     public ListViewAdapter(Context context, List<Map<String, Object>> listItems) {   
 32         this.context = context;            
 33         listContainer = LayoutInflater.from(context);   
 34         this.listItems = listItems;   
 35         hasChecked = new boolean[getCount()];   
 36     } 
 37     @Override
 38     public int getCount() {
 40         return listItems.size();
 41     }
 42 
 43     @Override
 44     public Object getItem(int position) {
 45        
 46         return null;
 47     }
 48 
 49     @Override
 50     public long getItemId(int position) {
 51         
 52         return 0;
 53     }
 54     
 55     private void checkedChange(int checkedID) {   
 56         hasChecked[checkedID] = !hasChecked[checkedID];   
 57     }   
 58    
 64     public boolean hasChecked(int checkedID) {   
 65         return hasChecked[checkedID];   
 66     }   
 67    
 72     private void showDetailInfo(int clickID) {   
 73         new AlertDialog.Builder(context)   
 74         .setTitle("物品详情:" + listItems.get(clickID).get("info"))   
 75         .setMessage(listItems.get(clickID).get("detail").toString())                 
 76         .setPositiveButton("确定", null)   
 77         .show();   
 78     }   
 79     
 80     @Override
 81     public View getView(int position, View convertView, ViewGroup parent) {
 82         
 83         Log.e("method", "getView");   
 84         final int selectID = position;   
 85        
 86         ListItemView  listItemView = null;   
 87         if (convertView == null) {   
 88             listItemView = new ListItemView();    
 89             
 90             convertView = listContainer.inflate(R.layout.list_item, null);   
 91            
 92             listItemView.image = (ImageView)convertView.findViewById(R.id.imageItem);   
 93             listItemView.title = (TextView)convertView.findViewById(R.id.titleItem);   
 94             listItemView.info = (TextView)convertView.findViewById(R.id.infoItem);   
 95             listItemView.detail= (Button)convertView.findViewById(R.id.detailItem);   
 96             listItemView.check = (CheckBox)convertView.findViewById(R.id.checkItem);   
 97            
 98             convertView.setTag(listItemView);   
 99         }else {   
100             listItemView = (ListItemView)convertView.getTag();   
101         }   
102
106         listItemView.image.setBackgroundResource((Integer) listItems.get(   
107                 position).get("image"));   
108         listItemView.title.setText((String) listItems.get(position)   
109                 .get("title"));   
110         listItemView.info.setText((String) listItems.get(position).get("info"));   
111         listItemView.detail.setText("商品详情");   
112       
113         listItemView.detail.setOnClickListener(new View.OnClickListener() {   
114             @Override  
115             public void onClick(View v) {   
116                
117                 showDetailInfo(selectID);   
118             }   
119         });   
120       
121         listItemView.check   
122                 .setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {   
123                     @Override  
124                     public void onCheckedChanged(CompoundButton buttonView,   
125                             boolean isChecked) {   
126                         
127                         checkedChange(selectID);   
128                     }   
129         });   
130            
131         return convertView;   
132     }
133 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值