文档章节

HowTo: ListView, Adapter

artshell
 artshell
发布于 2014/09/27 21:44
字数 615
阅读 35
收藏 1

I was surprised that getViewTypeCount() is so rarely overrided. If you are an expert in this – this post is not for you)

ListView and Adapter Basics

How it works:

1、ListView asks adapter “give me a view” (getView) for each item of the list
2、A new View is returned and displayed
Next question – what if we have one billion items? Create new view for each item? The answer is NO,Android caches views for you.

There’s a component in Android called “Recycler”.

1、If you have 1 billion items – there are only visible items in the memory + view in recycler.
2、ListView asks for a view type1 first time (getView) x visible items. convertView is null in getView – you create new view of type1 and return it.
3、ListView asks for a view type1 when one item1 is outside of the window and new item the same type is comming from the bottom. convertView is not null = item1. You should just set new data and return convertView back. No need to create view again.
Let’s write a simple code and put System.out to the getView:

public class MultipleItemsList extends ListActivity {
 
    private MyCustomAdapter mAdapter;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new MyCustomAdapter();
        for (int i = 0; i < 50; i++) {
            mAdapter.addItem("item " + i);
        }
        setListAdapter(mAdapter);
    }
 
    private class MyCustomAdapter extends BaseAdapter {
 
        private ArrayList mData = new ArrayList();
        private LayoutInflater mInflater;
 
        public MyCustomAdapter() {
            mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
 
        public void addItem(final String item) {
            mData.add(item);
            notifyDataSetChanged();
        }
 
        @Override
        public int getCount() {
            return mData.size();
        }
 
        @Override
        public String getItem(int position) {
            return mData.get(position);
        }
 
        @Override
        public long getItemId(int position) {
            return position;
        }
 
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("getView " + position + " " + convertView);
            ViewHolder holder = null;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.item1, null);
                holder = new ViewHolder();
                holder.textView = (TextView)convertView.findViewById(R.id.text);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }
            holder.textView.setText(mData.get(position));
            return convertView;
        }
 
    }
 
    public static class ViewHolder {
        public TextView textView;
    }
}


Different list items' layouts

Let’s move to the “more complicated” example. How about to add separator somewhere to the list.

You should do the following:

1、Override getViewTypeCount() – return how many different view layouts you have
2、Override getItemViewType(int) – return correct view type id by position
3、Create correct convertView (depending on view item type) in getView
Simple, isn’t it? Code snippet:

public class MultipleItemsList extends ListActivity {
 
    private MyCustomAdapter mAdapter;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new MyCustomAdapter();
        for (int i = 1; i < 50; i++) {
            mAdapter.addItem("item " + i);
            if (i % 4 == 0) {
                mAdapter.addSeparatorItem("separator " + i);
            }
        }
        setListAdapter(mAdapter);
    }
 
    private class MyCustomAdapter extends BaseAdapter {
 
        private static final int TYPE_ITEM = 0;
        private static final int TYPE_SEPARATOR = 1;
        private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
 
        private ArrayList mData = new ArrayList();
        private LayoutInflater mInflater;
 
        private TreeSet mSeparatorsSet = new TreeSet();
 
        public MyCustomAdapter() {
            mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
 
        public void addItem(final String item) {
            mData.add(item);
            notifyDataSetChanged();
        }
 
        public void addSeparatorItem(final String item) {
            mData.add(item);
            // save separator position
            mSeparatorsSet.add(mData.size() - 1);
            notifyDataSetChanged();
        }
 
        @Override
        public int getItemViewType(int position) {
            return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
        }
 
        @Override
        public int getViewTypeCount() {
            return TYPE_MAX_COUNT;
        }
 
        @Override
        public int getCount() {
            return mData.size();
        }
 
        @Override
        public String getItem(int position) {
            return mData.get(position);
        }
 
        @Override
        public long getItemId(int position) {
            return position;
        }
 
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            int type = getItemViewType(position);
            System.out.println("getView " + position + " " + convertView + " type = " + type);
            if (convertView == null) {
                holder = new ViewHolder();
                switch (type) {
                    case TYPE_ITEM:
                        convertView = mInflater.inflate(R.layout.item1, null);
                        holder.textView = (TextView)convertView.findViewById(R.id.text);
                        break;
                    case TYPE_SEPARATOR:
                        convertView = mInflater.inflate(R.layout.item2, null);
                        holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
                        break;
                }
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }
            holder.textView.setText(mData.get(position));
            return convertView;
        }
 
    }
 
    public static class ViewHolder {
        public TextView textView;
    }
}




本文转载自:http://android.amberfog.com/?p=296

共有 人打赏支持
artshell
粉丝 2
博文 56
码字总数 5163
作品 0
成都
程序员
私信 提问
Fragment中嵌入两个listview,从该fragment切换另外的fragment时闪退

初学者,请各位大神指点 //从该fragment切出时闪退 public class Main_Bottom_Me extends Fragment { private List meListViewperset = new ArrayList<>(); /* private List meListViewsett......

jeffblink
2017/06/12
78
0
ListView嵌套ListView缓存失效问题

ListView嵌套ListView缓存失效问题 Android中在写列表的时候,相信很多时候,我们都需要进行ListView嵌套ListView编程。比如说:帖子+评论页面的编写。然而这种模型是会出现被嵌套ListView缓...

精通吹水
2016/03/20
120
0
android listview addHeaderView和addFooterView的注意事项

今天在做项目的时候用了自定义listview以及自定义的item、adapter。现在把其中需要注意的地方记录下来: 1、item内如果有button等控件时,在监听listview的onitemclick事件时,焦点会被item内...

等待流星
2014/03/14
0
0
即时通讯发消息出现ListView左边视图突然闪现,再加载右边视图的bug

刚开始发送一条消息是这样处理的: conversation.addMessage(message); listView.setAdapter(adapter); adapter.refreshSelectLast(); 使得ListView刷新了2次,其中listView.setAdapter(ada......

xunfang
2016/01/22
28
0
《每日一剂》适配器刷新报错adapter.notifyDataSetChanged()解决

在使用ListView过程中,有时会出现The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a ......

王先森oO
05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

源码分析 Mybatis 的 foreach 为什么会出现性能问题

背景 最近在做一个类似于综合报表之类的东西,需要查询所有的记录(数据库记录有限制),大概有1W条记录,该报表需要三个表的数据,也就是根据这 1W 个 ID 去执行查询三次数据库,其中,有一...

TSMYK
15分钟前
0
0
IC-CAD Methodology企业实战之openlava

在云计算解决安全问题并成为IC界主流运算平台之前,私有的服务器集群系统仍然是各大IC公司的计算资源平台首选。 现在主流的服务器集群管理系统包括lsf,openlava,SkyForm,三者都属于lsf一系...

李艳青1987
30分钟前
2
0
http response stream 字节流 接收与解码

在接收图片、音频、视频的时候,需要用到二进制流。 浏览器会发给客户端 字节Byte流,一串串的发过来_int8格式 -128~127(十进制),也就是8bit(位)。 客户端接收的时候,对接收到的字节收集,...

大灰狼wow
30分钟前
2
0
配置Tomcat监听80端口...

12月13日任务 16.4 配置Tomcat监听80端口 16.5/16.6/16.7 配置Tomcat虚拟主机 16.8 Tomcat日志 1.配置Tomcat监听80端口 示例一:自定义监听端口 vim /usr/local/tomcat/conf/server.xml 编辑...

hhpuppy
31分钟前
3
0
在ubuntu中配置java环境

先在官网下载一个jdk 进入root权限,避免之后出现创建文件失败或者修改文本失败的问题 sudo i 创建一个文件夹来放置jdk解压后的文件 mkdir 文件夹mv jdk1.9(你下载的jdk文件) 你创建 的文...

无极之岚
31分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部