android开发之ExpandableListView的使用,实现类似QQ好友列表

来源:互联网 时间:1970-01-01

由于工作需要,今天简单研究了一下ExpandableListView,做了一个类似QQ列表的Demo,和大家分享一下。
效果图如下:

先来看看主布局文件:<http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">

这里我们不使用系统默认的分隔线,两个组之间的距离为8dp.

对于ExpandableListView,系统为我们提供了专门的适配器BaseExpandableListAdapter,我们可以自定义一个适配器继承BaseExpandableListAdapter,实现该类中的一些方法即可。代码如下:

public class MyAdapter extends BaseExpandableListAdapter { private List list; private Context context; public MyAdapter(List list, Context context) { this.list = list; this.context = context; } public MyAdapter() { } @Override public int getGroupCount() { return list.size(); } @Override public int getChildrenCount(int groupPosition) { return list.get(groupPosition).getChildren().size(); } @Override public Object getGroup(int groupPosition) { return list.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return list.get(groupPosition).getChildren().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) { GroupHolder holder; if (convertView == null) { holder = new GroupHolder(); convertView = LayoutInflater.from(context).inflate( R.layout.item_group, null); holder.title = (TextView) convertView .findViewById(R.id.group_title); holder.iv = (ImageView) convertView.findViewById(R.id.group_ico); convertView.setTag(holder); } else { holder = (GroupHolder) convertView.getTag(); } holder.title.setText(list.get(groupPosition).getGroupName()); if (isExpanded) { holder.iv.setImageResource(R.drawable.rounds_open); } else { holder.iv.setImageResource(R.drawable.rounds_close); } return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildHolder holder; if (convertView == null) { holder = new ChildHolder(); convertView = LayoutInflater.from(context).inflate( R.layout.item_child, null); holder.name = (TextView) convertView.findViewById(R.id.child_name); holder.sign = (TextView) convertView.findViewById(R.id.child_sign); convertView.setTag(holder); } else { holder = (ChildHolder) convertView.getTag(); } ChildBean cb = list.get(groupPosition).getChildren().get(childPosition); holder.name.setText(cb.getName()); holder.sign.setText([签名]+cb.getSign()); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return false; } class GroupHolder { TextView title; ImageView iv; } class ChildHolder { TextView name, sign; }}

这里的代码有点长,我们稍微解释一下,先是构造方法中传入两个参数,一个是数据源list,另外一个是上下文,list是一个GroupBean集合,GroupBean如下:

public class GroupBean { private String groupName; private List children; public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public List getChildren() { return children; } public void setChildren(List children) { this.children = children; } public GroupBean(String groupName, List children) { this.groupName = groupName; this.children = children; } public GroupBean() { }}

很明显,GroupBean有两个属性,一个是组名字,另外一个是该组下子项的一个集合,这个ChildBean就是每个组下面的每一个对象的数据,ChildBean代码如下:

public class ChildBean { private String name; private String sign; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public ChildBean(String name, String sign) { this.name = name; this.sign = sign; } public ChildBean() { }}

说完list,下面就是getGroupCount()和getChildrenCount(),这个有点类似于我们使用BaseAdapter时的getCount(),不同的是这里分别要返回每个组的数量,以及组内成员的数量,那么组的数量当然就是list.size(),组内成员的数量由于每组不同,所以要先拿到每个组,再拿到该组里成员的数量,代码就是list.get(groupPosition).getChildren().size();。接下来的两个方法就是getGroup()和getChild(),这个类似于BaseAdapter中的getItem,我们返回的时候还是组和组内的子项分开返回,代码很简单,就不多说了。稍微长一点的方法就是getGroupView和getChildView,不多也都没啥逻辑,和我们在ListView中使用BaseAdapter中的getView方法差不多,不同的是数据赋值的时候有差别。

我个人觉得,使用ExpandableListView关键在于把数据结构搞清楚,Group和Child搞清楚了,其他的都很简单。

这里我把Group的布局和Child的布局贴出来给大家看看:

item_group.xml

   

item_child.xml

   

这里还涉及到一个圆角方框,代码是这样的:
item_background_select.xml

  

好了,所有的准备工作都已经完成,下面看看怎么使用

public class MainActivity extends Activity { private ExpandableListView mListView; private MyAdapter adapter; private List list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化数据 initData(); mListView = (ExpandableListView) this.findViewById(R.id.my_listview); adapter = new MyAdapter(list, this); mListView.setAdapter(adapter); mListView.setGroupIndicator(null);// mListView.expandGroup(0); } private void initData() { list = new ArrayList(); { List list1 = new ArrayList(); ChildBean cb1 = new ChildBean(妈妈, 123); ChildBean cb2 = new ChildBean(爸爸, 456); ChildBean cb3 = new ChildBean(爷爷, 789); ChildBean cb4 = new ChildBean(妹妹, 000); list1.add(cb1); list1.add(cb2); list1.add(cb3); list1.add(cb4); GroupBean gb1 = new GroupBean(家, list1); list.add(gb1); } { List list1 = new ArrayList(); ChildBean cb1 = new ChildBean(张三, 123); ChildBean cb2 = new ChildBean(李四, 456); ChildBean cb3 = new ChildBean(王五, 789); ChildBean cb4 = new ChildBean(赵六, 000); ChildBean cb5 = new ChildBean(风起, 1111); ChildBean cb6 = new ChildBean(马坝, 222); ChildBean cb7 = new ChildBean(迁就, 3333333); list1.add(cb1); list1.add(cb2); list1.add(cb3); list1.add(cb4); list1.add(cb5); list1.add(cb6); list1.add(cb7); GroupBean gb1 = new GroupBean(我的朋友, list1); list.add(gb1); } { List list1 = new ArrayList(); ChildBean cb1 = new ChildBean(Tom, 123); ChildBean cb2 = new ChildBean(Jerry, 456); ChildBean cb4 = new ChildBean(Bush, 000); list1.add(cb1); list1.add(cb2); list1.add(cb4); GroupBean gb1 = new GroupBean(国际友人, list1); list.add(gb1); } { List list1 = new ArrayList(); ChildBean cb1 = new ChildBean(赵工, 123); ChildBean cb2 = new ChildBean(马工, 456); ChildBean cb3 = new ChildBean(王工, 789); ChildBean cb4 = new ChildBean(李工, 000); ChildBean cb5 = new ChildBean(为工, 000); list1.add(cb1); list1.add(cb2); list1.add(cb3); list1.add(cb4); list1.add(cb5); GroupBean gb1 = new GroupBean(同事, list1); list.add(gb1); } }}

这里有两行代码我稍微说一下mListView.setGroupIndicator(null);表示不使用系统提供的展开和收起的图标,mListView.expandGroup(0);表示默认打开第一项。

好了,就说这些,有问题欢迎留言讨论。

 

版权声明:本文为博主原创文章,未经博主允许不得转载。若有错误地方,还望批评指正,不胜感激。



相关阅读:
Top