zoukankan      html  css  js  c++  java
  • android开发之ExpandableListView的使用,实现类似QQ好友列表

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

    先来看看主布局文件:

    <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"
        android:background="#EDEDED"
        tools:context="com.example.expandablelistview.MainActivity" >
    
        <ExpandableListView
            android:id="@+id/my_listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginTop="10dp"
            android:divider="@null"
            android:dividerHeight="8dip" >
        </ExpandableListView>
    
    </RelativeLayout>

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

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

    public class MyAdapter extends BaseExpandableListAdapter {
    
        private List<GroupBean> list;
        private Context context;
    
        public MyAdapter(List<GroupBean> 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<ChildBean> children;
    
        public String getGroupName() {
            return groupName;
        }
    
        public void setGroupName(String groupName) {
            this.groupName = groupName;
        }
    
        public List<ChildBean> getChildren() {
            return children;
        }
    
        public void setChildren(List<ChildBean> children) {
            this.children = children;
        }
    
        public GroupBean(String groupName, List<ChildBean> 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

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@drawable/item_background_select" >
    
        <TextView
            android:id="@+id/group_title"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginLeft="36dp"
            android:gravity="center"
            android:text="好友分组"
            android:textSize="18sp" />
    
        <ImageView
            android:id="@+id/group_ico"
            android:layout_width="24dip"
            android:layout_height="24dip"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="12dp"
            android:layout_marginLeft="24dp"
            android:layout_marginRight="24dp"
            android:layout_marginTop="12dp"
            android:scaleType="centerInside"
            android:src="@drawable/rounds_close" />
    
        <TextView
            android:id="@+id/split_lines"
            android:layout_width="1dip"
            android:layout_height="48dp"
            android:layout_toLeftOf="@id/group_ico"
            android:background="#E6E6E6" />
    
    </RelativeLayout>

    item_child.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/child_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="10dip"
            android:text="姓名"
            android:textSize="18sp" />
    
        <TextView
            android:id="@+id/child_sign"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/child_name"
            android:paddingLeft="10dip"
            android:paddingRight="10dip"
            android:text="签名"
            android:textSize="12sp" />
    
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#B2DFEE" />
    
    </RelativeLayout>

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

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <corners android:radius="8dip" />
    
        <solid android:color="#FFFFFFFF" />
    
    </shape>

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

    public class MainActivity extends Activity {
    
        private ExpandableListView mListView;
        private MyAdapter adapter;
        private List<GroupBean> 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<GroupBean>();
            {
                List<ChildBean> list1 = new ArrayList<ChildBean>();
                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<ChildBean> list1 = new ArrayList<ChildBean>();
                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<ChildBean> list1 = new ArrayList<ChildBean>();
                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<ChildBean> list1 = new ArrayList<ChildBean>();
                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);表示默认打开第一项。

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

    本文源码下载地址https://github.com/lenve/expandablelistviewtest1

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

  • 相关阅读:
    mysql 删除与安装
    mysql 中文乱码 或 问号
    系统锁屏
    技术相关
    织梦 php 网站建设
    linux mysql 安装与使用
    技术收集
    批处理 关闭 进程
    二十三种设计模式
    三星(samsung)手机i699内容:解锁boot loader,刷recovery,刷机(刷rom),root综合教程
  • 原文地址:https://www.cnblogs.com/lenve/p/4925906.html
Copyright © 2011-2022 走看看