ListView 使用多布局的方法和简单的原理分析
来源:互联网 发布:绵阳广电网络营业厅 编辑:程序博客网 时间:2024/06/08 12:21
很多时候我们需要用到一个listview使用多个布局的情况,例如聊天的界面
这是从网上下载的图片,仅供参考。
实现:
下面来分析一下如何实现图中的效果:
如果要滑动的话,可以使用scrollView或者是listview, 但是scrollView 对于内存上无法实现view的复用,所以说不是一个好的方案。
使用listview就要使用多个布局文件,这个在android在baseadapter中已经为我们开放了非常方便的途径:
1、重写 int getItemViewType(int position)
在这个方法中返回我们来区别不同文件的tag,例如左边的聊天放回0, 右边的聊天放回1;
2、重写int getViewTypeCount
在这个方法中放回布局的个数,具体返回的大小,一会再做非常重要的解释。
先上传整体的伪代码:
import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public class TestAdapter extends BaseAdapter { private Context context; private List<ChatMessage> data; public TestAdapter(Context context, List<ChatMessage> data) { this.context = context; this.data = data; } @Override public int getItemViewType(int position) { // 左边的聊天放回0 ,右边的聊天返回1 return data.get(position).getType(); } @Override public int getViewTypeCount() { return 2; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int arg0) { return data.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } @Override public View getView(int position, View convertView, ViewGroup arg2) { // 获取当前位置的type, 0 为左边聊天, 1为右边的聊天 int type = getItemViewType(position); switch (type) { case 0: // 引用左边聊天的布局 convertView = LayoutInflater.from(context).inflate(..., null); // 展示内容的操作 ... break; case 1: // 引用右边聊天的布局 convertView = LayoutInflater.from(context).inflate(..., null); // 展示内容的操作 ... break; default: break; } return convertView; } private class ChatMessage { int type; public int getType() { return type; } }}
分析
代码非常的简单,其实还可以进行Holder这样的优化,这里只是简单说明一下使用的方法,就不具体优化了。
非常初级的api使用方法,完全没有什么难度,但是有一个问题一直困扰我很久:getViewTypeCount()这个方法中返回的这个值到底有什么用?
有的人会说:这里返回的是不同布局的个数。
经过我的测试,发现只要返回的值比 int getItemViewType(int position)这个方法中返回的最大值大就没有问题。例如上面的代码中,我们返回的type最大值是1,所以只要返回比1大的所有值都没问题。那么这种解释就说不通了。
今天又重新看了一下listview的复用机制才忽然意识到这个值到底起到了什么作用:
先简要说明listview的循环复用机制,一个listview至多为自己的item缓存 当前屏幕展示的个数 + 2, 滑动的时候把移除屏幕的item添加到缓冲区,回到屏幕时从缓冲区获取一个item来展示,这样就实现了item的复用,大大降低了内存的开销。具体的分析资料可以在郭霖老师和张鸿洋老师的博客中看到。
那么在listview多个布局的时候会发生怎么样的变化呢?
原理是还是一样的,唯一的不同就是我们之前重写的两个方法的返回了不一样的值。
1、 int getItemViewType(int position)
这个方法帮助listview区分不同的布局文件,缓冲布局文件的是一个数组,返回的int值就是缓冲区不同布局文件的下标,0 就代表 放在数组第一个位置, 1就代表放在第二个位置,需要复用的时候直接根据返回的int下标去获取需要的item, 如果不重写这个方法,那么位置肯定是唯一的,也就只有一个布局文件,我们可以猜测默认值是0;
2、int getViewTypeCount
在这个方法中返回的值就很重要了,他实际上是缓冲区的长度,所以这个值就必须要比getItemViewType(int position)返回的最大值要大,如果小的话,就会报数组越界异常,所以开头的问题就得到解决了。我们也可以猜测这个默认值返回的是1。
个人还是建议发挥恰当的值,例如 我们需要两个布局文件一个类型0, 一个类型100, 那么我们至少要设置长度是100, 中间的98个位置全是空的,作为一个开发者而言,是不允许这种站着茅坑不拉屎的行为发生的。
到这里这篇博客就结束了,希望这篇文章可以帮助大家去理解listview的实现原理。
- ListView 使用多布局的方法和简单的原理分析
- Android ListView实现不同item的方法和原理分析
- Android ListView实现不同item的方法和原理分析
- android Listview的getView和convertview原理解析以及使用不同的item布局(一)
- android Listview的getView和convertview原理解析以及使用不同的item布局(二)
- Activity在GridView和ListView之间切换使用一个布局实现的方法
- ListView的多布局和GridView
- ListView的多布局
- ListView的多布局
- ListView的多布局
- ListView实现多种item布局的方法和注意事项
- ListView实现多种item布局的方法和注意事项
- ListView的简单使用和性能优化
- 自定义listview和ProgressBar的简单使用
- 简单的ListView使用
- ListView的简单使用
- listview的简单使用
- ListView的简单使用
- 详解MVP矩阵之ViewMatrix
- 管理Java垃圾回收的五个建议
- 表格表单及样式重置、特性笔记
- 解决GitHub安装失败
- Android-开关按钮ToggleButton
- ListView 使用多布局的方法和简单的原理分析
- Mybatis与Spring整合连接MySQL
- MATLAB中字符串数组的创建和引用
- smplayer 不支持WMV,H264等格式的视频
- JSONObject json = JSONObject.fromObject(josnStr);报错
- 链表常用技巧:快行指针
- 重温for循环创建button
- 用pyenv解决在centos7下多版本python共存问题
- 获取当前系统的信息(CPU、物理内存、虚拟内存等