遇到一个需求,要实现树状图效果。往上看了一些,好像也都停繁琐的,不够简单,所以自己写了一个简单点的。感觉比一般的文章都简单。先看效果
而后台的数据是这样的
{
- "code": 200,
- "success": true,
- "data": [
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "机械",
- "sort": 0,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "children": [
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "无流量",
- "sort": -,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "泵",
- "sort": -,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "children": [
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "泵振动大",
- "sort": -1,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "流量不足",
- "sort": 0,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "泵温度高",
- "sort": 1,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "泵噪声大",
- "sort": 3,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "parentName": null,
- "hasChildren": true
- {
- "parentName": null,
- "hasChildren": true
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "电气",
- "sort": 1,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "children": [
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "马达",
- "sort": 0,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "children": [
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "马达不运转",
- "sort": 0,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "马达振动大",
- "sort": 1,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "马达温度高",
- "sort": 2,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "马达异常跳车",
- "sort": 3,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "马达噪声大",
- "sort": 4,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "id": "",
- "tenantId": "",
- "parentId": "",
- "code": "",
- "dictKey": "",
- "dictValue": "堵塞",
- "sort": 5,
- "remark": "",
- "isSealed": 0,
- "isDeleted": 0,
- "parentName": null
- {
- "parentName": null,
- "hasChildren": true
- {
- "parentName": null,
- "hasChildren": true
- {
- "msg": "操作成功"
}
首先数据里面并没有层级的字段,而层级后面用到,来控制item距离paddingleft的。所以我要加一个"cengji"字段。数据类型TreeBean如下,主要用到的红框里面的。
拿到接口里面的数据,先加一个层级处理
private void setTree(List<TreeBean> treeBeanList, int cengji) { for (TreeBean tree1 : treeBeanList) { tree1.setCengji(cengji); if (cengji == 1) { tree1.setShow(true); } if (tree1.isHasChildren()) { setTree(tree1.getChildren(), cengji + 1); } } }
处理完,就可以设置adapter了。adapter主要功能
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { if (viewHolder instanceof MyViewHolder) { TreeBean item = datalist.get(position); ((MyViewHolder) viewHolder).iv_expand.setImageResource(R.mipmap.expan); int cengji = item.getCengji(); if (cengji == 1) { ((MyViewHolder) viewHolder).ll_ceng.setVisibility(View.VISIBLE); } else { if (item.isShow()) { ((MyViewHolder) viewHolder).ll_ceng.setVisibility(View.VISIBLE); } else { ((MyViewHolder) viewHolder).ll_ceng.setVisibility(View.GONE); } } if (item.isExpanded()) { ((MyViewHolder) viewHolder).iv_expand.setRotation(-90); } else { ((MyViewHolder) viewHolder).iv_expand.setRotation(0); } int left = cengji * 60; ((MyViewHolder) viewHolder).ll_ceng.setPadding(left, 10, 0, 0); ((MyViewHolder) viewHolder).tv_shown.setText(item.getDictValue()); ((MyViewHolder) viewHolder).ll_ceng.setOnClickListener(new View.OnClickListener() { @SuppressLint("NotifyDataSetChanged") @Override public void onClick(View view) { if (mOnItemClickListener != null) { mOnItemClickListener.onItemClick(position); } item.setExpanded(!item.isExpanded()); if (item.isHasChildren()) { for (TreeBean tree : item.getChildren()) { boolean now = !tree.isShow(); if (now) { datalist.add(position + 1, tree); } else { item.setExpanded(false); tree.setExpanded(false); datalist.remove(tree); remotree(tree); } tree.setShow(now); } } notifyDataSetChanged(); } }); } } private void remotree(TreeBean treeBean) { if (treeBean.isHasChildren()){ for (TreeBean tree:treeBean.getChildren()){ datalist.remove(tree); tree.setExpanded(false); if (tree.isHasChildren()){ remotree(tree); } } } }
TreeAdapter的xml也很简单,
iv_expand就是一个箭头图标用来表示收缩或者伸展,旋转90度表示展开
<?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="wrap_content" android:orientation="vertical"> <LinearLayout android:id="@+id/ll_ceng" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dp10"> <ImageView android:id="@+id/iv_expand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/expan" /> <TextView android:id="@+id/tv_shown" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/dp10" android:text="xxx" android:textColor="@color/black" /> </LinearLayout> </LinearLayout>
主体xml也很简单,一个RecyclerView
<?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="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:layout_marginTop="@dimen/dp20" android:id="@+id/recycle_tree" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
recycle_tree = findView(R.id.recycle_tree); recycle_tree.setLayoutManager(new LinearLayoutManager(instance));
treeBeanList = JSONObject.parseArray(jsonObject.getString("data"), TreeBean.class); setTree(treeBeanList, 1); treeAdapter = new TreeAdapter(instance, treeBeanList); recycle_tree.setAdapter(treeAdapter);