首先看下效果可以感觉到很多app用到类似的功能,如果最常用的就是咱们的QQ聊天软件,好友分组就可以了用ExpandableListView实现;
ExpandableListView是ListView的子类:
ExpandableListView和ListView用法一样;
同样需要设置一个adapter;
唯一不同的是ListView只需要设置一组数据;而ExpandableListView需要设置组视图和子视图两组数据;
好了先来了解下ExpandAbleListAdapter:
相比ListViewAdapter就要稍微麻烦一些了;
首先需要设置组视图的标签总数、ID、内容 和 子视图的标签总数、ID、内容 还需指定位置相应的组试图;
最后在getGroupView()和getChildView()方法中对组视图和子视图进行设置;
是不是感觉方法很麻烦,但是用起来也非常简单;
比如:getGroupId(),getChildId()和BaseAdapter中的getItemId()方法一样不用管;
hasStableIds(),getGroupCount(),getGroup(),getChildrenCount(),getChild();这5个方法和BaseAdapter中的getCount()方法差不多,都是固定写法,而且非常简单;
唯一代码多一些的getGroupView(),getChildView()和BaseAdapter中的getView用法一模一样;
是不是瞬间感觉爽歪歪,看下具体代码吧:
class MyExpandableListAdapter extends BaseExpandableListAdapter {
@Override
//获取组视图标签总数
public int getGroupCount() {
return countryTypes.length;
}
@Override
//获取组视图标签的ID
public long getGroupId(int groupPosition) {
return 0;
}
@Override
//获取组视图标签内容
public Object getGroup(int groupPosition) {
return countryTypes[groupPosition];
}
@Override
//获得子视图标签的总数
public int getChildrenCount(int groupPosition) {
return childNames[groupPosition].length;
}
@Override
//获得子视图标签的ID
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
//获得组视图标签下子视图标签的内容
public Object getChild(int groupPosition, int childPosition) {
return childNames[groupPosition][childPosition];
}
@Override
//指定位置相应的组试图
public boolean hasStableIds() {
return true;
}
@Override
//对组视图标签进行设置
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder groupHolder;
if (convertView == null) {
convertView = View.inflate(context,R.layout.group_item,null);
groupHolder = new GroupHolder();
groupHolder.tv = (TextView)convertView.findViewById(R.id.textview);
groupHolder.iv= (ImageView) convertView.findViewById(R.id.imageview);
convertView.setTag(groupHolder);
} else {
groupHolder = (GroupHolder)convertView.getTag();
}
if(isExpanded){
//当组视图处于扩展状态的时候
groupHolder.tv.setText(getGroup(groupPosition).toString()+" ------ ↓");
}else {
groupHolder.tv.setText(getGroup(groupPosition).toString()+" ------ ↑");
}
return convertView;
}
@Override
/**
* 对组视图标签下的子视图标签进行设置
*
* @param groupPosition 组位置
* @param childPosition 子元素位置
* @param isLastChild 子元素是否处于组中的最后一个
* @param convertView 重用已有的视图(View)对象
* @param parent 返回的视图(View)对象始终依附于的视图组
*/
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ItemHolder itemHolder;
if(convertView==null){
convertView=View.inflate(context,R.layout.child_item,null);
itemHolder=new ItemHolder();
itemHolder.tv= (TextView) convertView.findViewById(R.id.textview);
itemHolder.iv= (ImageView) convertView.findViewById(R.id.imageview);
convertView.setTag(itemHolder);
}else {
itemHolder= (ItemHolder) convertView.getTag();
}
itemHolder.tv.setText(getChild(groupPosition,childPosition).toString());
itemHolder.iv.setBackgroundResource(childImageIds[groupPosition][childPosition]);
return convertView;
}
@Override
//当选择子节点的时候,调用此方法
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
elv= (ExpandableListView) findViewById(R.id.expandable_listview);
adapter = new MyExpandableListAdapter();
elv.setAdapter(adapter);
因为ExpandableListView有两个视图,所以条目点击事件也有两个,分别是:组视图的item点击事件,子视图的item点击事件
//组视图 item点击事件
elv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
ToastUtils.showToast(context,countryTypes[groupPosition]);
return false;
}
});
//子视图 item点击事件
elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,int groupPosition, int childPosition, long id) {
ToastUtils.showToast(context,childNames[groupPosition][childPosition]);
return false;
}
});