ExpandableListView使用心得

来源:互联网 发布:淘宝油画 莫奈的花园 编辑:程序博客网 时间:2024/06/06 02:34

背景:刚到新公司半个月,项目新版本即将上线。测试给我提了六七个bug,我看了一下发现都是在同一个界面中出现的。而该部分代码是离职同事码的,我第一时间想到的是产品已经经上线一年多了,为啥现在才测出来。虽然有很多总原因,但归根究底是因为重视程度不够。我想很多安卓开发都有相似的遭遇。既然bug提给我了,我本身做事有认真负责,撸起袖子看代码、缕逻辑。话说这代码谁看谁都想吐槽两句,怎么可以这么乱。经过我的深思熟虑,决定抛弃他的代码-重构。接下来我先研究ios的该部分产品逻辑,然后按照自己的想法重写。
正文:说了这么多题外话,咱们言归正传。这个界面主要就是通过ExpandableListView实现的。本人之前很少使用该控件,所以想通过此文将我在使用中遇到的问题纪录下,以便后续查阅,同时也希望对同行有所帮助。
首先说说使用方法:
1.新建布局文件,如下

<?xml version="1.0" encoding="utf-8"?> <ExpandableListView             xmlns:android="http://schemas.android.com/apk/res/android"             android:id="@+id/elv"             android:layout_width="fill_parent"             android:layout_height="fill_parent"             android:cacheColorHint="#00000000"             android:scrollbars="none"/>

2.创建BaseExpandableListAdapter适配器(今天的主角),继承该适配器时,需实现下面这些方法,

public class Test extends BaseExpandableListAdapter {    @Override    public int getGroupCount() {        return 0;//获取组的数量    }    @Override    public int getChildrenCount(int groupPosition) {        return 0;//获取每个组下孩子的数量    }    @Override    public Object getGroup(int groupPosition) {        return null;//获取组对应的数据对象    }    @Override    public Object getChild(int groupPosition, int childPosition) {        return null;//获取孩子的数据对象    }    @Override    public long getGroupId(int groupPosition) {        return groupPosition;//获取组id    }    @Override    public long getChildId(int groupPosition, int childPosition) {        return childPosition;//获取孩子id    }    @Override    public boolean hasStableIds() {        return false;//表示孩子是否和组ID是跨基础数据的更改稳定    }    @Override    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {        return null;//自定义组UI    }    @Override    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {        return null;//自定义孩子UI    }    @Override    public boolean isChildSelectable(int groupPosition, int childPosition) {        return false;//孩子在指定的位置是否可选的      }}

而我想实现的效果如下图,你会发现child视图有两种,group视图一种。
所以我们就需要用到getChildType和getChildTypeCount这两个方法。
这就是本文的核心了!
这里写图片描述

private static final int TYPE_RECEIVING = 0;private static final int TYPE_GRAB = 1;@Override    public int getChildType(int groupPosition, int childPosition) {        if(isShowGrabSetting() && isGrabGroup(groupPosition)){            return TYPE_GRAB;        }        return TYPE_RECEIVING;    }    @Override    public int getChildTypeCount() {        return 2;    }    @Override    public View getChildView(int parentPos, int childPos, boolean          b, View view, ViewGroup viewGroup) {        if(getChildType(parentPos, childPos) == TYPE_RECEIVING){            view = bindReceivingChild(view, parentPos);        } else if(getChildType(parentPos, childPos) == TYPE_GRAB){            view = bindGrabChild(view, parentPos, childPos);        }        return view;    }

这是我的具体实现,因为有两种视图所以getChildTypeCount返回2。这里有一点值得注意的是getChildType中返回的值必须是从0~getChildTypeCount-1
如果你想让某个按钮点击时有展开和关闭child视图的功能时,你需要用到expandGroup(pos)和collapseGroup(pos)这两个方法。其中有个坑就是,如果点击时child视图中有变化时,需要先调用notifyDataSetChanged(),再去调用上面两个方法。

推荐:https://github.com/yzl520/PullLeftToRefreshLayout一个很好的横向刷新控件,感兴趣的同学可以看看哦。
好了,就先写到这里。谢谢查阅!

1 0
原创粉丝点击