背景:刚到新公司半个月,项目新版本即将上线。测试给我提了六七个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一个很好的横向刷新控件,感兴趣的同学可以看看哦。
好了,就先写到这里。谢谢查阅!