ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项。这些子项来自于与该视图关联的BaseExpandableListAdapter。
有时候简单的ExpandableListView不能满足我们的需求,比如下面这样的需求:
这就需要在ExpandableListView里面再嵌套一个ListView来实现。首先需要重写一个ListView,代码如下:
- public class SubListView extends ListView {
- public SubListView(android.content.Context context,
- android.util.AttributeSet attrs) {
- super(context, attrs);
- }
- public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
- MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
- }
- }
主要是重写onMeasure方法,这里将heightMeasureSpec参数设大,否则,嵌套的ListView会显示不全。
然后重写我们的BaseExpandableListAdapter,代码如下:
- class ExpandAdapter extends BaseExpandableListAdapter {
- private Context context;
- private ArrayList<ArrayList<String>> childList;
- private ArrayList<String> groupList;
- private LayoutInflater inflater;
- public ExpandAdapter(Context context, ArrayList<String> groupList,
- ArrayList<ArrayList<String>> childList) {
- this.childList = childList;
- this.groupList = groupList;
- this.context = context;
- inflater = LayoutInflater.from(context);
- }
- @Override
- public int getGroupCount() {
- // TODO Auto-generated method stub
- return groupList.size();
- }
- @Override
- public int getChildrenCount(int groupPosition) {
- // TODO Auto-generated method stub
- // return childList.get(groupPosition).size();
- return 1;
- }
- @Override
- public Object getGroup(int groupPosition) {
- // TODO Auto-generated method stub
- return groupList.get(groupPosition);
- }
- @Override
- public Object getChild(int groupPosition, int childPosition) {
- // TODO Auto-generated method stub
- return childList.get(groupPosition).get(childPosition);
- }
- @Override
- public long getGroupId(int groupPosition) {
- // TODO Auto-generated method stub
- return 0;
- }
- @Override
- public long getChildId(int groupPosition, int childPosition) {
- // TODO Auto-generated method stub
- return 0;
- }
- @Override
- public boolean hasStableIds() {
- // TODO Auto-generated method stub
- return true;
- }
- @Override
- public View getGroupView(int groupPosition, boolean isExpanded,
- View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- View groupView = null;
- if (convertView == null) {
- groupView = newGroupView(parent);
- } else {
- groupView = convertView;
- }
- bindGroupView(groupPosition, groupView);
- return groupView;
- }
- private View newGroupView(ViewGroup parent) {
- return inflater.inflate(R.layout.group_item_layout, null);
- }
- private void bindGroupView(int groupPosition, View groupView) {
- TextView tv = (TextView) groupView.findViewById(R.id.name_text);
- tv.setText(groupList.get(groupPosition));
- ImageView iv = (ImageView) groupView
- .findViewById(R.id.image_avatar);
- iv.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Toast.makeText(context, "Hello!", Toast.LENGTH_SHORT)
- .show();
- }
- });
- }
- @Override
- public View getChildView(int groupPosition, int childPosition,
- boolean isLastChild, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- View childView = null;
- if (convertView == null) {
- childView = newChildView(parent, groupPosition);
- } else {
- childView = convertView;
- }
- bindChildView(groupPosition, childPosition, childView);
- return childView;
- }
- private View newChildView(ViewGroup parent, final int groupPosition) {
- View v = inflater.inflate(R.layout.child_layout, null);
- SubListView listView = (SubListView) v.findViewById(R.id.sublistview);
- View foot = inflater.inflate(R.layout.foot_layout, null);
- listView.addFooterView(foot);
- // final SubListAdapter adapter = new
- // SubListAdapter(treeNodes.get(groupPosition).childs,layoutInflater);
- final SubListAdapter adapter = new SubListAdapter(
- childList.get(groupPosition), inflater);
- listView.setAdapter(adapter);// 设置菜单Adapter
- listView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // TODO Auto-generated method stub
- // if(position ==
- // treeNodes.get(groupPosition).childs.size()){//foot的点击事件处理
- // treeNodes.get(groupPosition).childs.add("New Add");
- // adapter.notifyDataSetChanged();
- // }else{
- // Toast.makeText(parentContext, "当前选中的是:" + position,
- // Toast.LENGTH_SHORT).show();
- // }
- if (position == childList.get(groupPosition).size()) {// foot的点击事件处理
- childList.get(groupPosition).add("New Add");
- adapter.notifyDataSetChanged();
- } else {
- Toast.makeText(ExpandableListViewActivity.this,
- "当前选中的是:" + position, Toast.LENGTH_SHORT)
- .show();
- }
- }
- });
- return v;
- }
- private void bindChildView(int groupPosition, int childPosition,
- View groupView) {
- // TextView tv = (TextView) groupView.findViewById(R.id.name_text);
- // tv.setText(childList.get(groupPosition).get(childPosition));
- }
- @Override
- public boolean isChildSelectable(int groupPosition, int childPosition) {
- // TODO Auto-generated method stub
- return true;
- }
- }
这里需要注意的是在getChildrenCount方法里要返回1,不然就会每个二级View里就会生成很多ListView。加载很多其实就是靠ListView的foot的点击事件来处理的。
这里对ExpandableListView也做了一些其他的处理,一并记录下。第一个是将一级View的指示符号放到里右面并且进行了自定义。放到右面的方法如下:
- <span style="font-size:18px;">int width = getWindowManager().getDefaultDisplay().getWidth();
- expandableListView.setIndicatorBounds(width - 100, width - 10);</span>
自定义指示符的方法是在res/drawable下自定义一个xml命名为indicator.xml,如下:
- <span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_expanded="true" android:drawable="@drawable/add_btn_small" />
- <item android:state_expanded="false" android:drawable="@drawable/head32_32" />
- </selector></span>
然后在我们的layout里做以下处理:
- <span style="font-size:18px;">android:groupIndicator="@drawable/indicator"</span>
这样就会显示我们自定义的View了,需要注意的一点是这里的图片容易拉伸,最好用.9的图。
第二个问题是默认将ExpandableListView默认打开,这个就比较简单了,
- private void expandView() {
- for (int i = 0; i < groupList.size(); i++) {
- expandableListView.expandGroup(i);
- }
- }
有问题交流。