ExpandableListView的常用属性的使用(一)
在使用过RecyclerView的朋友们再使用这个可能会发现,这TM怎么会这样,原因无外乎两点:
1、 在从源头传递数据时RecyclerView是传递一个数据源过去,而ExpandListView是传递2个不同的数据源(前提是json数据不规范的情况下)
2、 RecyclerView在它的adapter中可以实现多布局,但是一定要再套入ListView或者GridView来展示多布局的内容(这样就又要给ListView写adapter),而ExpandListView在它的adapter中也可以实现多布局(一般为2种,也可以多种子项),但是不需要频繁的嵌入ListView或者GridView来展示内容,组件自带的只要数据源是List集合就可以实现ListView的展示效果。
下面展示ExpandListView的项目效果图:
看完上面的内容,相信你已迫不及待的想看看代码了,下面我将奉上我这没什么组织的代码层。
首先,我需要3个数据源,相信会问,为什么要3个,一个最外层的Group类目,一个内层的Child类目,那还有一个呢,是我们用于点击的Child类目下的id(实际运用中需要传递这样的id去执行刷新界面的操作)
1、创建数据源并初始化
private List<String> groupData; //1级类目数据源
private List<List<String>> childData; //2级类目数据源
private List<List<String>> childDataID; //2级类目数据源下对应的id
private ProductList_Filter_CategoryAdapter2 categoryAdapter2; //ExpandListView的适配器
private ExpandableListView product_store_categoryList;//记得去初始化它的id
... ...
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.productlist_filter_normal2, container, false);
ButterKnife.inject(this, view);
initDatas(); //初始化数据源
initUI(); //UI调整
initListener(); //监听事件
return view;
}
//初始化数据源
private void initDatas() {
groupData = new ArrayList<String>();
childData = new ArrayList<List<String>>();
childDataID = new ArrayList<List<String>>();
}
2、UI界面的交互以及adapter的数据绑定
private void initUI() {
categoryAdapter2 = new ProductList_Filter_CategoryAdapter2(groupData, childData, new WeakReference<Context>(getActivity()), null);
categoryAdapter2.setData(groupData, childData);
product_store_categoryList.setAdapter(categoryAdapter2);
if (categoryAdapter2.getGroupCount() > 0) { //默认展开第一项分组
product_store_categoryList.expandGroup(0);
} product_store_categoryList.setGroupIndicator(null);//将控件默认的左边箭头去掉
}
3、ExpandListView的监听事件
一、2级类目的点击监听事件:
product_store_categoryList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int groupPosition, int childPosition, long id) {
String idChild = childDataID.get(groupPosition).get(childPosition); //获取2级类目中点击的哪一项的id
getProductByCategoryStoreChild(idChild);//自定义方法去执行跳转刷新操作(我项目中使用的是发广播的方式)
return false;
}
});
二、1级类目的点击监听事件:
(实现只展开一个2级类目的效果:)
方法一:
//先定义一个标记来记录2级列表的展开状态
private int sign = 0;//控制列表的展开
然后我们的思路是:
1、由于设置的是默认打开第一级类目下的二级类目,所以这里要将第一个位置和其他位置分开来做判断;
2、在有子类情况下,执行for循环来关闭(collapseGroup)其他无关非点击项下的2级类目,打开(expandGroup)当前点击项下的2级类目;
3、在group没有child的情况下,不展开group ,执行 最后return返回的boolean来判断。
//这个方法可实现打开点击项的2级类目,关闭其他2级类目(但是我使用中出现个问题就是:在我既使用了group监听又使用了child监听时会出现2级类目下的数据重复现象)
product_store_categoryList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int groupPosition, long id) {
if (groupPosition == 0) { //第一个类目
if (sign == 0) { // 0 的时候表示是打开状态
product_store_categoryList.collapseGroup(sign);
sign = 1;
} else { //1 的时候表示是闭合状态
for (int i = 0; i < categoryAdapter2.getGroupCount(); i++) {
if (groupPosition != i) {
product_store_categoryList.collapseGroup(i); //收起其他层
}
}
product_store_categoryList.expandGroup(groupPosition, true);
sign = 0;
}
} else {
if (sign == 0){
sign = 1;
}else {
sign = 0;
}
for (int i = 0; i < categoryAdapter2.getGroupCount(); i++) {
if (groupPosition != i) {
product_store_categoryList.collapseGroup(i); //收起其他层
}
}
product_store_categoryList.expandGroup(groupPosition, true);
}
if (childData.get(groupPosition).isEmpty()) { //如果没有2级分类情况分析
return true;
} else {
categoryAdapter2.notifyDataSetChanged();
return false;
}
// return false;//默认为false,设为true时,点击事件不会展开Group
}
});
方法二:(推荐使用)
//不用GroupClick的监听,改用GroupExpand来实现是否展开1级类目(不会有数据重复的现象,值得推荐)
product_store_categoryList.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int i) {
for (int j = 0; j < categoryAdapter2.getGroupCount(); j++) {
if (j != i) {
product_store_categoryList.collapseGroup(j); //收起其他层
}
}
}
});
补充:
对ExpandableListView去掉默认箭头和互斥展开
private ExpandableListView expandListView;
1、去掉默认箭头
expandListView.setGroupIndicator(null);
2、互斥展开
expandListView.setOnGroupExpandListener(new OnGroupExpandListener(){
public void onGroupExpand(int groupPosition) {
for (int i = 0; i < adapter.getGroupCount(); i++) {
// ensure only one expanded Group exists at every time
if (groupPosition != i && expandListView.isGroupExpanded(groupPosition)) {
expandListView.collapseGroup(i);
}
}
}
});