最近在做这么一个功能,如图,
不知道我画 的清楚不清楚,整体的是一个大的列表,黄色部分就是列表每个项的名称,剩下的都是他的子项,刚开始我整体用expandlistview,然后子集里面的嵌套了一个griedview与一个listview,是不是很傻,虽然可以正常显示,但是点击后,滑动,再绑定listview的时候就错位了,但是我也重写每个listview和griedview 的onMeasure方法了呀,也还是到处有问题,我想可能是因为滑动,复位的原因,导致了错位,网上也不建议这种嵌套太多的代码,再想想,说白了,这个功能只有两点,1.整体的一个显示,2.点击后的显示,关键是点击后容易出问题,经过在群里询问,问大神们,一大神教了我一个办法就是把listview和griedview这两个不要拆开,看成一个item,在expandlistview绑定的时候根据不同的类型返回不同的布局,点击的时候将点击后的索引值存储起来(我这里用的是hashmap)下面把这个功能最重要的部分分享给大家,重点就在expandablelistAdapter里面
public class HemeExpandableListAdapter extends BaseExpandableListAdapter {
@SuppressWarnings("unused")
private Context context;
private int TYPE_GRIEDVIEW = 0, TYPE_LISTITEM = 1;
List<IndexRecommendTypes> groups;
private final LayoutInflater listContainer;// 视图容器
private ListItemView listItemView = null;// 父节点
private ChildListItemView childItemView = null;// 子节点
private HashMap map = new HashMap(); //存储每个组的选中项
public HemeExpandableListAdapter(Context context,
List<IndexRecommendTypes> groups) {
this.groups = groups;
this.context = context;
this.listContainer = LayoutInflater.from(context); // 创建视图容器并设置上下文
}
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groups == null ? 0 : groups.size();
}
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
//判断缓存组是否为空
if(map!=null && map.size()>0){
//判断是否包含该组项,若包含,那么获取该组的子集数量,否则获取默认第一个的子集数量
if(map.containsKey(groupPosition))
{
return groups.get(groupPosition).getChildProductTypeList().get(Integer.parseInt(map.get(groupPosition).toString()))
.getAppProductDTOs().size() + 1;
}
}
return groups.get(groupPosition).getChildProductTypeList().get(0)
.getAppProductDTOs().size() + 1;
}
// 获取一级节点
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groups.get(groupPosition);
}
// 获取所有子集
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return groups.get(groupPosition).getChildProductTypeList()
.get(childPosition + 1);// groups.get(groupPosition).getAppProductDTOs().get(childPosition);//
// 获取子列表
}
// 父id
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
// 子id
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
// 如果为TRUE,意味着相同的ID永远引用相同的对象
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
class ListItemView { // 自定义控件集合
public TextView groupname;
}
class ChildListItemView {
public MyDrawLineGridView grid_chid_sort;
// 子集列表复用
public TextView childname;
public ImageView courseimg;
public TextView peoplenum;
public TextView teachername;
public TextView teacherLabel;
}
apdater最主要的两个部分,一个是获取组的数据,二是获取自己的数据
1.获取组数据,组只有1个textview,比较简单
// 绑定一级列表
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
// 获取list_item布局文件的视图
convertView = listContainer.inflate(
R.layout.lv_expand_group_layout, null);
listItemView = new ListItemView();
// 获取控件对象
listItemView.groupname = (TextView) convertView
.findViewById(R.id.txt_group_name);// 名称
// 设置控件集到convertView
convertView.setTag(listItemView);
} else {
listItemView = (ListItemView) convertView.getTag();
}
IndexRecommendTypes group = groups.get(groupPosition);
listItemView.groupname.setText(group.getProductTypeName());// 设置组名
return convertView;
}
2.获取子集数据,这时子集分类有两部分,一部分为greidview的数据,另一部分为expandlistview的子集item项,我们返回连个不同的类型用来区分greidview和item,将griedview搁置到第一个位置
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// 根据不同的类型,来选择不同的布局文件,将griedview增加到item上
int childType = getChildType(groupPosition, childPosition);
ChildListItemView childItemView = null;
if (convertView == null) {
childItemView = new ChildListItemView();
// 判断为哪个item
if (childType == TYPE_GRIEDVIEW)// greidview形式
{
convertView = listContainer.inflate(R.layout.expand_child_item,
null);
childItemView.grid_chid_sort = (MyDrawLineGridView) convertView
.findViewById(R.id.grid_child_sort);
} else// 列表的item
{
convertView = listContainer.inflate(
R.layout.lv_expand_child_layout, null);
childItemView = new ChildListItemView();
childItemView.childname = (TextView) convertView
.findViewById(R.id.txt_first);
childItemView.courseimg = (ImageView) convertView
.findViewById(R.id.img_big);// 头像
childItemView.peoplenum = (TextView) convertView
.findViewById(R.id.txt_peaple_num);
childItemView.teachername = (TextView) convertView
.findViewById(R.id.txt_teacher_name);
childItemView.teacherLabel = (TextView) convertView
.findViewById(R.id.txt_money);
}
convertView.setTag(childItemView);
} else {
// 获取tag
childItemView = (ChildListItemView) convertView.getTag();
}
// 赋值
if (childType == TYPE_GRIEDVIEW)// griedview
{
// 绑定greidview
final List<ChildProductTypeList> childdata = groups.get(
groupPosition).getChildProductTypeList();
//这里是用来判断选中的是第几个griedview的项,用来变换颜色背景,就不贴griedview的adapter列表了
int sIndex=0;
if(map!=null && map.size()>0)
{
if(map.containsKey(groupPosition))
{
sIndex=Integer.parseInt(map.get(groupPosition).toString());
}
}
//griedview的绑定数据列表
HomeChildSortAdapter adapter = new HomeChildSortAdapter(context,
childdata,sIndex);
childItemView.grid_chid_sort.setAdapter(adapter);
//大分类
final int gposition=groupPosition;
// griedview点击事件,点击变下面的列表数据
childItemView.grid_chid_sort
.setOnItemClickListener(new OnItemClickListener() {
@SuppressWarnings("unchecked")
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
// TODO Auto-generated method stub
//保存点击的是第几组第几个griedview的项
map.put(gposition, position);
notifyDataSetChanged();
}
});
} else// 列表
{
// 获取每个组的实体类
final IndexRecommendTypes itemdata = groups.get(groupPosition);
final AppProductDTOs childdata;// 子分类下的列表数据
//判断缓存是否为空,并判断是否点击了该组。若已经点击,显示该组下的列表,否则显示默认第一组下的子集数据
if(map!=null && map.size()>0){
if(map.containsKey(groupPosition))
{
childdata = groups.get(groupPosition).getChildProductTypeList()
.get(Integer.parseInt(map.get(groupPosition).toString())).getAppProductDTOs()
.get(childPosition - 1);
}
else
{
childdata = groups.get(groupPosition).getChildProductTypeList()
.get(0).getAppProductDTOs().get(childPosition - 1);
}
}
else
{
childdata = groups.get(groupPosition).getChildProductTypeList()
.get(0).getAppProductDTOs().get(childPosition - 1);
}
childItemView.childname.setText(childdata.getProductName());
childItemView.peoplenum.setText("" + childdata.getClickCount());
String teacherName = childdata.getTeachers();
childItemView.teacherLabel.setVisibility(View.VISIBLE);
if (!TextUtils.isEmpty(teacherName)) {
childItemView.teachername.setText(teacherName);
} else {
childItemView.teacherLabel.setVisibility(View.INVISIBLE);
childItemView.teachername.setText("");
}
//这里图片显示我用的是imageloader
ImageLoader.getInstance().displayImage(childdata.getProductImg(), childItemView.courseimg ,BitmapUtil.getPersonLoading());
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//子项的点击事件,可以跳转可以做任何事。
}
});
}
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return false;
}
//重点,一定要返回2个类型的布局,一个是griedview的布局,另一个是linerout的布局(相当于listview的item)
@Override
public int getChildTypeCount() {
// TODO Auto-generated method stub
return 2;
}
// 返回不同type类型的布局
@Override
public int getChildType(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
if (childPosition == 0) {
return TYPE_GRIEDVIEW;// 带有griedview的
} else {
return TYPE_LISTITEM;// listview列表的item项
}
}
expandablelistadapter就完成了,代码有点乱,但是思想就是这样实现的,我在网上找到很多就是expandlistview嵌套greidview的,但是他们下面都没有列表了,而我这种功能下面还有很多列表,好了,第一次自己把自己写的代码贴出来,写的不好,见笑,如有问题之处还忘大家积极指正出来,我会积极改正,也希望有遇到这种功能的时候,能够帮助到大家,这是我最终的目的,谢谢大家!