一般复杂的ListView都会重写BaseAdapter,通过重用convertView来减少inflate,通过setTag()和ViewHolder改变ItemView的内容。

重写BaseAdapter必须要实现

public int getCount()

public Object getItem(int position)

public View getView(int position, View convertView, ViewGroup parent)

这三个函数。

补充一下ListView的ViewHolder机制:

在Android中inflate是比较耗费资源的,如果每次getView都执行inflate,那么很容易造成内存溢出,所以要在getView中重用convertView,如果convertView已经进行了inflate,那么只要对view进行赋值就可以,比如setText()。所以当convertView为空时才会执行inflate,当convertView不为空时,只执行赋值操作。通过给convertView设置一个tag来记录view的引用,还可以减少findViewById()的次数。

在默认情况下,Adapter只保存一个convertView,可以简单的认为,每次getView()时的convertView都是上次getView时return的view。这种情况显然是不能实现多种类型的ItemView的,如何才能在getView时让convertView是我们想要的布局类型呢,BaseAdapter还有两个可以重写的函数:

public int getItemViewType(int position)

public int getViewTypeCount()

看到这两个函数应该很多人都明白了,getViewTypeCount()就是获取列表有几种布局类型,getItemViewType(int position)是获取在position位置上的布局类型。

通过一个小Demo来测试一下,写一个有3中布局的列表,3中布局分别是TextView,EditText,Button,

首先实现列表的ListItem

package com.example.testmultipletypelist;

public class ListItem {

    public static final int TYPE_TEXT = 0;
    public static final int TYPE_EDIT = 1;
    public static final int TYPE_BUTTON = 2;
    public static final int TYPE_COUNT = 3;

    private String name;
    private int type;

    public ListItem(int type, String name) {
        this.type = type;
        this.name = name;
    }

    public int getType() {
        return type;
    }

    public String getName() {
        return name;
    }
}

重写BaseAdapter中的getItemViewType()和getViewTypeCount()。

    @Override
    public int getItemViewType(int position) {
        if (list != null && position < list.size()) {
            return list.get(position).getType();
        }
        return super.getItemViewType(position);
    }

    @Override
    public int getViewTypeCount() {
        return ListItem.TYPE_COUNT;
    }

然后在getView()中,可以通过getItemViewType()来处理不同的布局

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int type = getItemViewType(position);
        switch (type) {
        case ListItem.TYPE_TEXT: {
            TextViewHolder holder = null;
            if (convertView == null) {
                convertView = activity.getLayoutInflater().inflate(R.layout.list_test_item, null);
                holder = new TextViewHolder();
                holder.textView = (TextView) convertView.findViewById(R.id.tv_text);
                convertView.setTag(holder);
            } else {
                holder = (TextViewHolder) convertView.getTag();
            }
            holder.textView.setText(list.get(position).getName());
            break;
        }
        case ListItem.TYPE_EDIT: {
            EditViewHolder holder = null;
            if (convertView == null) {
                convertView = activity.getLayoutInflater().inflate(R.layout.list_edittext_item, null);
                holder = new EditViewHolder();
                holder.editText = (EditText) convertView.findViewById(R.id.ed_edittext);
                convertView.setTag(holder);
            } else {
                holder = (EditViewHolder) convertView.getTag();
            }
            holder.editText.setText(list.get(position).getName());
            break;
        }
        case ListItem.TYPE_BUTTON: {
            ButtonViewHolder holder = null;
            if (convertView == null) {
                convertView = activity.getLayoutInflater().inflate(R.layout.list_button_item, null);
                holder = new ButtonViewHolder();
                holder.button = (Button) convertView.findViewById(R.id.btn_button);
                convertView.setTag(holder);
            } else {
                holder = (ButtonViewHolder) convertView.getTag();
            }
            holder.button.setText(list.get(position).getName());
            break;
        }
        default:
            break;
        }

        return convertView;
    }

运行效果

Demo下载

Android ListView添加多种类型的ItemView的更多相关文章

  1. Android开发之ListView添加多种布局效果演示

    在这个案例中展示的新闻列表,使用到ListView控件,然后在适配器中添加多种布局效果,这里通过重写BaseAdapter类中的 getViewType()和getItemViewType()来做判断 ...

  2. Android进阶笔记11:ListView篇之ListView显示多种类型的条目(item)

    ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...

  3. Android进阶笔记10:ListView篇之ListView显示多种类型的条目(item)

    ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...

  4. ListView之多种类型Item

    一.概述 一般而言,listview每个item的样式是一样的,但也有很多应用场景下不同位置的item需要不同的样式. 拿微信举例,前者的代表作是消息列表,而后者的典型则是聊天会话界面. 本文重点介绍 ...

  5. ListView显示多种类型的item

    ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似 这是MainActivity:,MainActivity的布局就是一个ListView public class Mai ...

  6. Android ListView 显示多种数据类型

    ListView往往可能会有不同的数据类型,单类型的数据可能运用会比较少些,这也是最近项目中的一个需求{在发送消息的时候,需要选择联系人,而联系人列表由英文字母索引+联系人组成},上一篇文章只是一个基 ...

  7. android listview 添加数据

    <span style="white-space:pre"> </span>listView = (ListView) findViewById(R.id. ...

  8. Android ListView Adapter的getItemViewType和getViewTypeCount多种布局

     <Android ListView Adapter的getItemViewType和getViewTypeCount多种布局> 在Android的ListView中.假设在一个Lis ...

  9. Android之listview添加数据篇

    一.ListView: 1. ListView通常有两个职责: 1.向布局填充数据 2.处理选择点击等操作 2.ListView的创建需要3个元素: 1. ListView中的每一列的View. 2. ...

随机推荐

  1. 设置参数进行启动的Python脚本模板

    # coding:utf-8 from optparse import OptionParser def migrate_func(): print 'You give the migrate arg ...

  2. Entity Framework 实体框架的形成之旅--几种数据库操作的代码介绍(9)

    本篇主要对常规数据操作的处理和实体框架的处理代码进行对比,以便更容易学习理解实体框架里面,对各种数据库处理技巧,本篇介绍几种数据库操作的代码,包括写入中间表操作.联合中间表获取对象集合.递归操作.设置 ...

  3. 能分组的GridView

    有天在想工作上的事的时候,看着.net原有的DataGridView,想起以前我写过的一篇文章,总结了一个好的Gird控件应该具备哪些功能,在那里我提及到了分组功能,就像jqGrid那样, 其实这样的 ...

  4. Win10 QQ五笔默认中文,InputMode默认中文

    Win10系统安装了QQ五笔后,InputMode默认英文,必须用鼠标点或者按 Ctrl+空格才能转换为中文.非常不方便. 即使将微软拼音默认为中文也不管用,解决方法如下: 设置后,无论你打开运行.记 ...

  5. httpclient 调用WebAPI

    1.创建webapi项目,提供接口方法如下: /// <summary> /// 获取租户.位置下的所有传感器 /// </summary> /// <returns&g ...

  6. 提高生产性工具(四) - XML数据库的尝试

    首先祝大家新年快乐.身体健康,平安就是福气. 对于一般的个人迷你项目,数据量不大的时候,完全没有必要使用数据库,管理数据使用XML就可以了. 自己尝试写了一个XML数据库,插入1w条小记录,大概3M大 ...

  7. sqlserver中的循环遍历(普通循环和游标循环)

    sql 经常用到循环,下面介绍一下普通循环和游标循环 1.首先需要一个测试表数据Student

  8. WITH RECURSIVE and MySQL

    WITH RECURSIVE and MySQL If you have been using certain DBMSs, or reading recent versions of the SQL ...

  9. Firemonkey TComboBox 下拉菜单字型修改方法 (D10)

    在 FMX 下的 TComboBox 下拉菜单字型修改有二种方法: uses FMX.Pickers; 使用 Style,需先设定好 Style 后,再指定预设项的 Style,方法如下: proce ...

  10. php中的常用数组函数(七) 数组合并 array_merge()和array_merge_recursive()

    $arr1 = array(1, 2, 3, 4, 'color'=>'red'); $arr2 = array('a', 'b', 'c', 'color'=>'blue'); prin ...