自定义ExpandableListView分割线

时间:2024-04-05 13:22:02

最近为了符合UI的要求,所以重新定义了ExpandableListView中的child的layout,布局,而且为了以后可以更好的对分割线进行控制,所以对分割线进行了重新定义。

思路如下 ,自定义ExpandableListView分割线

以前我们在实现二级菜单的时候要对Group 和Child 的分别加载layout布局 ,加载完成后通过getView的方式进行展示出来,恰好我们可以利用这一点来区分且进行设置不同的样式


自定义ExpandableListView分割线

以前分割线的样式比较单一,而且要适应美工的要求有些困难,所以我把它写入到了一个layout里面,我们可以在Expandablelistview的适配器中进行处理,首先我们可以先正常的进行数据的填充,但是在布局中将分割线都设置为空,自定义ExpandableListView分割线

也就是这个效果,而在自定义的分隔线View 中,



public MyExpandableSpliteLine(BaseExpandableListAdapter expandableListView) {
    this(expandableListView, R.layout.group_divider, R.layout.child_divider);
}

public MyExpandableSpliteLine(BaseExpandableListAdapter expandableListView, int groupline, int childline) {
    this.elv = expandableListView;
    this.groupline = groupline;
    this.childline = childline;
}

首先 得先梳理一下Expandable的执行流程




@Override
public int getChildTypeCount() {
    return elv.getChildTypeCount() + 1;
}

@Override
public int getGroupTypeCount() {
    return elv.getGroupTypeCount() + 1;
}


@Override
public int getGroupType(int groupPosition) {
    
    return isView(groupPosition) ? elv.getGroupType(groupPosition / 2) : getGroupTypeCount() - 1;
}

@Override
public int getChildType(int groupPosition, int childPosition) {
    
    return isView(groupPosition) && !isView(childPosition) ? elv.getChildType(groupPosition / 2, childPosition / 2) : getChildTypeCount() - 1;
}

//用来区分当前想要绘制的View 是 View还是分割线View 
private boolean isView(int index) {

    return index % 2 == 0;
}


//在填充至新的adapter时候,要注意 count已经翻倍啦  因为新添加了分割线的View 


@Override
public int getGroupCount() {
    int groupCount =elv.getGroupCount();
    return groupCount * 2;
}

@Override
public int getChildrenCount(int groupPosition) {
   int childCount = elv.getChildrenCount(groupPosition);
   return childCount * 2;
}



@Override
public Object getGroup(int groupPosition) {

    if (isView(groupPosition))
        return elv.getGroup(groupPosition / 2);
    else
        return groupPosition;

}


@Override
public Object getChild(int groupPosition, int childPosition) {
	 return elv.getChild(groupPosition, childPosition);
}

@Override
public long getGroupId(int groupPosition) {
	return getCombinedGroupId(groupPosition);
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return getCombinedChildId(groupPosition, childPosition);
}

@Override
public boolean hasStableIds() {
    return elv.hasStableIds();
}


最后对View 进行绘制的时候 我们只需要区分



@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    
    if (isView(groupPosition))//判断当前View为GroupView,直接getGroupView就行
        return elv.getGroupView(groupPosition , isExpanded, convertView, parent);

	//根据type来判断,当前是分割线View

    if (convertView == null && getGroupType(groupPosition) == getGroupTypeCount() - 1)
        return LayoutInflater.from(parent.getContext()).inflate(this.groupline, parent, false);
    else
       return convertView;
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    
    if (isView(groupPosition) && !isView(childPosition))
        return elv.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);

    if (getChildType(groupPosition, childPosition) == getChildTypeCount() - 1)
        return LayoutInflater.from(parent.getContext()).inflate(childline, parent, false);
    else

        return convertView;
}

运行结果如下:


初步判定原因,应该出现在这里
@Override
public int getGroupCount() {
    
    int groupCount =elv.getGroupCount();
    return groupCount * 2;
}


@Override
public int getChildrenCount(int groupPosition) {

   
    int childCount = elv.getChildrenCount(groupPosition);
    return childCount * 2;

}
childview中也包括分割线View ,如果是分割线View的话,我们能获取到的childcount应该是0


@Override
public int getChildrenCount(int groupPosition) {


    if (isView(groupPosition)) {
        int childCount = elv.getChildrenCount(groupPosition % 2);
        return childCount * 2;
    } else
        return 0;

}

//groupposition当前已经翻倍,也就是说不再是0,1,2,3,4,5样式
//而是0,2,4,6....所以在获取的时候groupPosition/2 这一点在处理点击事件时候也会涉及


@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    
    if (isView(groupPosition))//判断当前View为GroupView,直接getGroupView就行
        return elv.getGroupView(groupPosition/2, isExpanded, convertView, parent);

	//根据type来判断,当前是分割线View

    if (getGroupType(groupPosition) == getGroupTypeCount() - 1)
        return LayoutInflater.from(parent.getContext()).inflate(this.groupline, parent, false);
    else
       
        return convertView;
}


最后效果图:

	

	


有些粗糙 需要改进的地方也很多  还得努力!


Github地址:https://github.com/uvfv1991/MyExpandableListViewLine