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

  • 相关阅读:
    HDU1879 kruscal 继续畅通工程
    poj1094 拓扑 Sorting It All Out
    (转)搞ACM的你伤不起
    (转)女生应该找一个玩ACM的男生
    poj3259 bellman——ford Wormholes解绝负权问题
    poj2253 最短路 floyd Frogger
    Leetcode 42. Trapping Rain Water
    Leetcode 41. First Missing Positive
    Leetcode 4. Median of Two Sorted Arrays(二分)
    Codeforces:Good Bye 2018(题解)
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461739.html
Copyright © 2011-2022 走看看