Android分组ListView(Sectioned Headers in ListViews for Android) 问题 当你想展示一个分类的数据列表比如依据时间、日期、产品累不或者销售价格序等 解决方案我们可以使用“Sectioned headers“(这里不知道应该具体叫啥,故未翻译,可以理解为分割头,或
Android分组ListView(Sectioned Headers in ListViews for Android)
问题
当你想展示一个分类的数据列表比如依据时间、日期、产品累不或者销售价格序等
解决方案我们可以使用“Sectioned headers“(这里不知道应该具体叫啥,故未翻译,可以理解为分割头,网站空间,或者分组) ListView.这里我们自定义一个Adapter,使用不同类型的视图和其对应的Adapter来实现,这里我们必须关注2个方法:
int
getItemViewType(int position)
为特定的视图返回getView(int, View, ViewGroup)即将构建的视图类型
int
getViewTypeCount()
返回getView(int, View, ViewGroup)即将构建的视图的视图类型个数.
下面是我们的实现代码:
我们这里构建我们的Android工程,并添加一个GroupListVeiwActivity(Project的包名:com.jeriffe.app)
首先我们需要定义我们的Layout文件:
注:这里我们有3个Layout文件,分别是activity的Layout,sectionsHeader的Layout,及listView Item的Layout,以下只是演示,故Layout代码文件格式并未应用Theme及Style
activity_group_list_veiw.xml(activity的Layout)
group_list_header.xml(sectionsHeader的Layout)
(listView Item的Layout)?
接下来便是我们需要自定义的一个Adapter
我们添加一个新的类:SeparatedListAdapter 继承自BaseAdapter适配器类,以下代码已经很直白,关键代码已经添加了注释,最重要的4个方法如下粗体所示package com.jeriffe.app;
import java.util.LinkedHashMap;
import java.util.Map;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
public class SeparatedListAdapter extends BaseAdapter {
public final Map sections = new LinkedHashMap();
public final ArrayAdapter headers;
public final static int TYPE_SECTION_HEADER = 0;
public SeparatedListAdapter(Context context) {
headers = new ArrayAdapter(context, R.layout.group_list_header);
}
public void addSection(String section, Adapter adapter) {
this.headers.add(section);
this.sections.put(section, adapter);
}
public Object getItem(int position) {
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return section;
if (position < size)
return adapter.getItem(position - 1);
// otherwise jump into next section
position -= size;
}
return null;
}
public int getCount() {
// total together all sections, plus one for each section header
int total = 0;
for (Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public boolean areAllItemsSelectable() {
return false;
}
@Override
public int getViewTypeCount() {
// assume that headers count as one, then total all sections
int total = 1;
for (Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
@Override
public int getItemViewType(int position) {
int type = 1;
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return TYPE_SECTION_HEADER;
if (position < size)
return type + adapter.getItemViewType(position - 1);
// otherwise jump into next section
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
@Override
public boolean isEnabled(int position) {
// 设置header enabled is false,通俗点就是点击header无效
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for (Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// check if position inside this section
if (position == 0)
return headers.getView(sectionnum, convertView, parent);
if (position < size)
return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
public long getItemId(int position) {
return position;
}
}
接下来便是我们的Activity类