• Android 中ListView,BaseAdapter,CursorAdapter等的简单总结


    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 }

     

          

  • 相关阅读:
    如何将本地的项目,上传到github
    Pytest 失败重运行
    Jenkins项目构建成功后,配置邮件
    Jenkins构建UI自动化项目,指定本地执行,没弹起浏览显示
    pytest_重写pytest_sessionfinish方法的执行顺序_结合报告生成到发送邮件
    python +pytestreport 生成测试报告_报告没有生成图标和报告样式错乱
    Jenkins的搭建及配置
    Jenkins构建项目遇到的问题总结
    pytest_terminal_summary重写收集测试报告并发送邮件,报错"Argument(s) {'Config'} are declared in the hookimpl but can not be found in the hookspec"
    Jenkins创建任务进行构建项目配置
  • 原文地址:https://www.cnblogs.com/carmanloneliness/p/2370597.html
Copyright © 2020-2023  润新知