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

最开始的时候,打算把两种数据类型放入一个List<Object>中,参考上一篇随笔的状态保持的实现,在代码写完了开始测试的时候,发现问题众多,上下滚动的时候左边的CheckBox的选择状态没有很好的保存,会出现混乱选择的情况,于是参考网上的一些做法{寻找的参考方法并没有描述像这样稍稍复杂点的情况,都是TextView,没有状态的保持,没有View的重用,所以写了这篇随笔}并延伸总结;
MutiTypeAdapter.java

public class MutiTypeAdapter extends BaseAdapter {
private OnSelectedItemChanged listener;
private List<ListItem> list;
private LayoutInflater inflater; public MutiTypeAdapter(Context context, List<ListItem> list,
OnSelectedItemChanged listener) {
super();
this.list = list;
inflater = LayoutInflater.from(context);
this.listener = listener;
} @Override
public int getCount() {
return list.size();
} @Override
public Object getItem(int position) {
return list.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// 重点
View view = list.get(position).getView(convertView, inflater);
if (list.get(position).getClass() == BEntity.class) { // 如果是BEntity,也就是上面图中左边有CheckBox的项
final BEntity entity = (BEntity) list.get(position);
final CheckBox cb = entity.cbox;
cb.setChecked(entity.isChecked());
cb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
entity.setChecked(cb.isChecked()); // 更改List中Entity的选择状态
if (listener != null) {
listener.onClick(getSelectedItem(list)); // 接口的思想暴露给Activity选择了多少项,当然也可以具体点通知Activity选择了哪些项
}
}
});
}
return view;
} public int getSelectedItem(List<ListItem> list) { // 获取选择了多少项
int i = 0;
for (ListItem item : list) {
if (item.isChecked()) {
i++;
}
}
return i;
} public interface OnSelectedItemChanged {
public void onClick(int count);
}
}

上面是数据源适配器,最开始的时候我在getView方法中对Item进行数据类的判断(AEntity/BEntity),再决定是选择加载哪一个layout,结果发现在重用View的时候很混乱,所以改为上面的实现方法;
AEntity和BEntity都继承自接口ListItem

public class AEntity implements ListItem {
private String str; public AEntity(String str) {
super();
this.str = str;
} @Override
public View getView(View convertView, LayoutInflater inflater) {
Holder holder = null;
if (convertView == null
|| convertView.getTag().getClass() != Holder.class) {
holder = new Holder();
convertView = inflater.inflate(getLayoutId(), null);
TextView tv = (TextView) convertView.findViewById(R.id.title_tv);
holder.tv = tv;
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.tv.setText(str);
return convertView;
} class Holder {
TextView tv;
} @Override
public int getLayoutId() {
return R.layout.title;
} @Override
public boolean isChecked() { // 此Entity相当于是标题项,没有CheckBox,所以永远返回false
return false;
}
}
public class BEntity implements ListItem {
private boolean isChecked = false;
private String str; public boolean isChecked() {
return isChecked;
} public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
} public BEntity(String str) {
super();
this.str = str;
} @Override
public int getLayoutId() {
return R.layout.child;
} public CheckBox cbox; @Override
public View getView(View convertView, LayoutInflater inflater) {
Holder holder = null;
if (convertView == null
|| convertView.getTag().getClass() != Holder.class) {
holder = new Holder();
convertView = inflater.inflate(getLayoutId(), null);
TextView tv = (TextView) convertView.findViewById(R.id.item_tv);
CheckBox cb = (CheckBox) convertView.findViewById(R.id.item_cb);
holder.tv = tv;
holder.cb = cb;
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.tv.setText(str);
final CheckBox cb = holder.cb;
this.cbox = cb;return convertView;
} class Holder {
TextView tv;
CheckBox cb;
}
}

ListItem.java

public interface ListItem {
public boolean isChecked(); // 当前项是否选中 public int getLayoutId(); public View getView(View convertView, LayoutInflater inflater); // 返回Adapter中需要返回的View
}

在MainActivity中,模拟数据源并绑定到ListView列表;

public class MainActivity extends Activity {
ListView lv;
MutiTypeAdapter adapter; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
setAdapter();
} private void setAdapter() {
List<ListItem> list = new ArrayList<ListItem>();
for (int i = 0; i < 50; i++) {
if (i % 2 == 0) {
list.add(new AEntity("item - " + i));
} else {
list.add(new BEntity("item - " + i));
}
}
OnSelectedItemChanged listener = new OnSelectedItemChanged() { @Override
public void onClick(int count) {
Log.e("SelectedCount", count + "");
}
};
adapter = new MutiTypeAdapter(getApplicationContext(), list, listener);
lv.setAdapter(adapter);
}
}

OK,通过几步就实现了所想要的功能!

Android ListView 显示多种数据类型的更多相关文章

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

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

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

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

  3. ListView显示多种类型的item

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

  4. Android ListView显示不同样式的item

    先look图 我们再使用listview时,listview的item大多时候都是一种样式,在很多app中也很常见,但有时候根据需求,可能数据的数量不一样,同个类型的数据显示的位置不同,亦或者有的it ...

  5. Android ListView显示底部的分割线

    有些时候,我们会提出这样的需求,希望ListView显示底部(顶部)的分割线,这样做,会使得UI效果更加精致,如下图所示: 如果搜索资料,大家会搜到一堆相关的方法,最多的莫过于设置listview的f ...

  6. Android ListView添加多种类型的ItemView

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

  7. Android ListView显示访问WebServices返回的JSON结果

    1.WebServices的返回结果 2.ListView内容布局代码 <?xml version="1.0" encoding="utf-8"?> ...

  8. Android ListView滑动过程中图片显示重复错乱闪烁问题解决

    最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决 主要分析Android ListView滚动过程中图片显示重复.错乱.闪烁的原因及解决方法,顺带提及L ...

  9. Android ListView分页加载时图片显示问题

    场景:Android ListView需要分页加载,每个item中会有图片,图片又是从网络下载的. 问题:在滑动加载下一页时,上一页的图片明明已经下载完成了,但是无法显示出来. Bug重现: 1,加载 ...

随机推荐

  1. dubbo之基础应用

    一.Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单 ...

  2. JDBC 工具类模板c3p0

    JDBC 工具类模板 package com.itheima.sh.utils; import com.mchange.v2.c3p0.ComboPooledDataSource; import ja ...

  3. http性能测试点滴

    WeTest 导读 在服务上线之前,性能测试必不可少.本文主要介绍性能测试的流程,需要关注的指标,性能测试工具apache bench的使用,以及常见的坑. 什么是性能测试 性能测试是通过自动化的测试 ...

  4. 开发发布npm module包

    开发发布npm module包 问题 在项目开发过程中,每当进入一个新的业务项目,从零开始搭建一套前端项目结构是一件让人头疼的事情,就要重新复制一个上一个项目的前端框架和组件代码库.其中很多功能的模块 ...

  5. 【WXS全局对象】Number

    属性: 名称 说明 Number.MAX_VALUE 返回JS中可表示的最大的数.它的近似值为 1.7976931348623157 x 10308. Number.MIN_VALUE 返回JS中可表 ...

  6. lintcode112 删除排序链表中的重复元素

    删除排序链表中的重复元素   给定一个排序链表,删除所有重复的元素每个元素只留下一个. 您在真实的面试中是否遇到过这个题? Yes 样例 给出 1->1->2->null,返回 1- ...

  7. JAVA 面试须知

    本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺. 1. Java中的原始数据类型都有哪些, ...

  8. 爬虫1.5-ajax数据爬取

    目录 爬虫-ajax数据爬取 1. ajax数据 2. selenium+chromedriver知识准备 3. selenium+chromedriver实战拉勾网爬虫代码 爬虫-ajax数据爬取 ...

  9. linux服务器操作小技巧

    python程序后台一直运行,并将打印信息输出到文件中 nohup -u test.py > out.txt & -u 表示无缓冲,直接将打印信息输出带文件中 &表示程序后台运行

  10. CodeForces 908C. New Year and Curling 解题报告 Java

    1. 思路 这题实际上是个几何问题——两个外相切的圆,由勾股定理,他们的纵坐标有以下的规律: 则有$$y_{n+1} = y_{n} + \sqrt{(2r)^2 - (x_{n} - x_{n+1} ...