序言
前一段有一些需求,就是企业级的通讯录,需要从服务器端下载,但是由于企业级通讯录会比较大,消耗用户流量(比如,我只想找一下张三,但是我第一次打开通讯录就会把整个公司的通讯录都请求下来,而且企业级的通讯录很大,加载时间也会比较长,流量消耗也会比较多,所以这给用户的体验是十分不友好的),因此,我们把企业级的通讯录做成多级树结构,用户打开通讯录模块,只会把一级目录结构请求下来,当用户需要查找人时,点击对应的部门item,就会请求对应部门下的列表,这样在极大程度上减少了用户的流量消耗和等待时间。因此,就有了下面的文章。
效果图和思路
该需求的难点:
1.多级树的缩进展示(数据结构的设计)
2.多种情况的展示(正常、单选、多选等)
3.控制条目侧滑
一、多级树的实现
当时拿到需求,考虑到使用expandlistview,但是由于需求不是太一致,所以放弃了使用。然后查阅了相关的资料,决定使用listview,缩进每个item来达到多级树的目录结构。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:divider="@color/transparent"
android:dividerHeight="0dp"></ListView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/line"
/>
</LinearLayout>
二、单选多选等情况的实现
根据需求,会有不同Activity跳转到通讯录选人,所以会有多选和单选,本文主要实现了单选和多选的样式和相关逻辑,如有需要,只需要修改,然后写回调就可以拿到选中数据。
三、条目侧滑的实现
关于侧滑,listview并没有提供类似recycleview那样的api,而网上很多侧滑,都是自定义listview,这样侵入性太强,结合起来会比较麻烦,而且有的还存在bug。在次,我使用的注释张的SwipeMenuLayout,只需要在item布局上做文章就可以,简单方便,而且强大。http://blog.csdn.net/zxt0601/article/details/52303781
代码的实现
1.请求服务器端,拿到数据,按照本地的bean格式修改数据源
/**
* 第一次的数据源
*
* @param res
* @return
*/
public List<Node> initNodeRoot(List<ContactTreeListOut> res) { //核心代码
ArrayList<Node> roots = new ArrayList<Node>(); //根节点列表
for (ContactTreeListOut ct : res) {
Node node = new Node(ct.getName(), "0".equals(ct.getIsNone()) ? "dept" : "people", "", ct.getId(), -1, ct.getIsNone());
roots.add(node);
}
return roots;
}
2.本地Node相关代码,由于比较多,只贴一下构造方法
/**
* 设置节点值
*
* @param parentkey 父节点id
* @param item_id 自己id
* @param isNone 是否是部门,1是/0否
*/
public Node(String simlpleName, String value, String parentkey, String item_id, int iconId, String isNone) {
this.simpleName = simlpleName;
this.value = value;
this.parentkey = parentkey;
this.icon = iconId;
this.item_id = item_id;
this.isNone = isNone;
}
3.Adapter的初始化
/**
* @param context 响应监听的上下文
*