2014最后一篇,记ExpandableListViewd的自定义
首先看下效果图,看着效果一步一步实现它
说先是两个布局,一个是group_item_layout.xml,是一级项的布局,一个是child_item_layout.xml,是二级项的布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:id="@+id/group_name" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_marginLeft="35dip" android:gravity="center_vertical" /> <TextView android:id="@+id/group_count" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_marginLeft="5dip" android:gravity="center_vertical" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:descendantFocusability="blocksDescendants" android:minHeight="40dp" android:orientation="horizontal"> <!--android:descendantFocusability="blocksDescendants"如果不设置子项将不能点击--> <ImageButton android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="2dip" android:layout_marginRight="10dip" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="match_parent"> <TextView android:id="@+id/item_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" /> <TextView android:id="@+id/item_detail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginTop="10dp" /> </RelativeLayout> </LinearLayout>
二级项里面有一个图片在最前面显示,然后是两个TextView,一个显示标题,一个显示描述.
然后是主布局,activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ExpandableListView android:id="@+id/expand_listview" android:layout_width="match_parent" android:layout_height="match_parent"> </ExpandableListView> </RelativeLayout>
主布局里就一个ExpanableListView
编写Group和Child对应的Item实体类
package cn.edu.zafu.expand; public class GroupItem { private String name; public GroupItem(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package cn.edu.zafu.expand; public class ChildItem { private int resId; private String name; private String detail; public ChildItem(int resId, String name, String detail) { this.resId = resId; this.name = name; this.detail = detail; } public int getResId() { return resId; } public void setResId(int resId) { this.resId = resId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } }
最重要的一步就是适配器了
package cn.edu.zafu.expand; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; public class MyBaseExpandableListAdapter extends BaseExpandableListAdapter { private Context mContext = null; private LayoutInflater mInflater = null; private List<GroupItem> mGroup = null; private List<List<ChildItem>> mChild = null; public MyBaseExpandableListAdapter(Context context, List<GroupItem> group, List<List<ChildItem>> child) { mContext = context; mGroup = group; mChild = child; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getGroupCount() { return mGroup.size(); } @Override public int getChildrenCount(int groupPosition) { return mChild.get(groupPosition).size(); } @Override public List<ChildItem> getGroup(int groupPosition) { return mChild.get(groupPosition); } @Override public ChildItem getChild(int groupPosition, int childPosition) { return mChild.get(groupPosition).get(childPosition); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public boolean hasStableIds() { return false; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View view = null; GroupViewHolder viewHolder = null; if (convertView == null) { view = mInflater.inflate(R.layout.group_item_layout, null); viewHolder = new GroupViewHolder(); viewHolder.mGroupName = (TextView) view.findViewById(R.id.group_name); viewHolder.mGroupCount = (TextView) view.findViewById(R.id.group_count); view.setTag(viewHolder); } else { view = convertView; viewHolder = (GroupViewHolder) view.getTag(); } viewHolder.mGroupName.setText(mGroup.get(groupPosition).getName()); viewHolder.mGroupCount.setText("[" + mChild.get(groupPosition).size() + "]"); return view; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { View view = null; ChildViewHolder viewHolder = null; if (convertView == null) { view = mInflater.inflate(R.layout.child_item_layout, null); viewHolder = new ChildViewHolder(); viewHolder.mIcon = (ImageView) view.findViewById(R.id.img); viewHolder.mChildName = (TextView) view.findViewById(R.id.item_name); viewHolder.mDetail = (TextView) view.findViewById(R.id.item_detail); view.setTag(viewHolder); } else { view = convertView; viewHolder = (ChildViewHolder) view.getTag(); } viewHolder.mIcon.setBackgroundResource(getChild(groupPosition, childPosition).getResId()); viewHolder.mChildName.setText(getChild(groupPosition, childPosition).getName()); viewHolder.mDetail.setText(getChild(groupPosition, childPosition).getDetail()); return view; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } private class GroupViewHolder { TextView mGroupName; TextView mGroupCount; } private class ChildViewHolder { ImageView mIcon; TextView mChildName; TextView mDetail; } }
适配器的关键点事继承BaseExpandableListAdapter,并覆盖重写里面的抽象方法
最后是Activity的代码,具体见注释
package cn.edu.zafu.expand; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ExpandableListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private ExpandableListView mExpandableListView = null; private MyBaseExpandableListAdapter mAdapter = null; private List<GroupItem> mGroup = new ArrayList<GroupItem>(); private List<List<ChildItem>> mChild = new ArrayList<List<ChildItem>>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData();//初始化数据 mExpandableListView = (ExpandableListView) findViewById(R.id.expand_listview); //mExpandableListView.setGroupIndicator(null);//前面的指示器设为无 mAdapter = new MyBaseExpandableListAdapter(this, mGroup, mChild);//新建适配器 mExpandableListView.setAdapter(mAdapter);//设置适配器 mExpandableListView.setOnGroupClickListener(new MyOnGroupClickListener());//设置Group点击监听 mExpandableListView.setOnChildClickListener(new MyOnChildClickListener());//设置Child点击监听 } /* 数据初始化 */ private void initData() { GroupItem groupItem = null; groupItem = new GroupItem("我的设备"); mGroup.add(groupItem); groupItem = new GroupItem("我的好友"); mGroup.add(groupItem); groupItem = new GroupItem("陌生人"); mGroup.add(groupItem); List<ChildItem> child = null; ChildItem childItem = null; child = new ArrayList<ChildItem>(); childItem = new ChildItem(R.drawable.expland_child_item, "我的电脑", "[在线]无需数据线,手机轻松传文件到电脑"); child.add(childItem); childItem = new ChildItem(R.drawable.expland_child_item, "我的打印机", "将手机文件或照片发送到电脑连接的打印机"); child.add(childItem); mChild.add(child); child = new ArrayList<ChildItem>(); childItem = new ChildItem(R.drawable.expland_child_item, "羽人", "[在线]过去哪都不重要"); child.add(childItem); childItem = new ChildItem(R.drawable.expland_child_item, "梦想逝去", "[在线]后来我眼瞎了"); child.add(childItem); childItem = new ChildItem(R.drawable.expland_child_item, "啊飒飒", "[离线请留言]"); child.add(childItem); mChild.add(child); child = new ArrayList<ChildItem>(); childItem = new ChildItem(R.drawable.expland_child_item, "话说撒", "[在线]自行车自行车XC"); child.add(childItem); childItem = new ChildItem(R.drawable.expland_child_item, "法规发生的变成", "[在线]啊实打实大学"); child.add(childItem); childItem = new ChildItem(R.drawable.expland_child_item, "的感受到", "[离线请留言]"); child.add(childItem); mChild.add(child); } /* 一级事件监听 */ class MyOnGroupClickListener implements ExpandableListView.OnGroupClickListener { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { int count = mAdapter.getChildrenCount(groupPosition); Toast.makeText(getApplicationContext(), "拥有的子类个数:" + count, Toast.LENGTH_SHORT).show(); return false;//返回false能继续处理展开动作,如果返回了true,则二级项不能展开 } } /* 二级事件监听 */ class MyOnChildClickListener implements ExpandableListView.OnChildClickListener { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { ChildItem item = mAdapter.getChild(groupPosition, childPosition); Toast.makeText(getApplicationContext(), "你点击了" + item.getName(), Toast.LENGTH_SHORT).show(); return true;//事件被处理了返回true不能继续处理事件 } } }
整个流程下来可能二级项会出现不能点击的情况,这时候需要将二级项的布局文件里的所有Layout里增加属性,我这里只是增加了根layout,内部layout并没有增加,发现这样后也是可以点击的,于是内部layout就没有加这个属性了
android:descendantFocusability="blocksDescendants"同时适配器里的方法isChildSelectedable要返回true
@Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; }