flutter-树形目录展示

把数据处理成node这样的,直接调用就ok.


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'Node.dart';

void main() {
  runApp(new MaterialApp(
    home: MyTree(),
  ));
}

class MyTree extends StatefulWidget {
  @override
  State createState() {
    // TODO: implement createState
    return MyTreeState();
  }
}

class MyTreeState extends State {
  List expand = new List();

  ///保存所有数据的List
  List list = new List();
  List mark = new List();

  @override
  void initState() {
    buildNode();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('tree'),
      ),
      body: Container(
        child: Column(
          children: _buildNode(expand),
        ),
      ),
    );
  }

  ///构建元素
  List _buildNode(List nodes) {
    print('buildNode:' + nodes.length.toString());
    List widgets = List();
    if (nodes != null && nodes.length > 0) {
      for (Node node in nodes) {
        widgets.add(GestureDetector(
          child: ImageText(10.0 * node.depth, node.object.toString(),
              node.expand, node.isHasChildren),
          onTap: () {
            if (node.isHasChildren) {
              if (node.expand) {
                //之前是扩展状态,收起列表
                node.expand = false;
                _collect(node.nodeId);
              } else {
                //之前是收起状态,扩展列表
                node.expand = true;
                _expand(node.nodeId);
              }
              setState(() {});
            }
          },
        ));
      }
    }
    return widgets;
  }

  ///第一个节点的index
  int nodeId = 1;

  ///扩展机构树:id代表被点击的机构id
  /// 做法是遍历整个list列表,将直接挂在该机构下面的节点增加到一个临时列表中,
  ///然后将临时列表插入到被点击的机构下面
  void _expand(int id) {
    //保存到临时列表
    List tmp = new List();
    for (Node node in list) {
      if (node.fatherId == id) {
        tmp.add(node);
      }
    }
    //找到插入点
    int index = -1;
    int length = expand.length;
    for (int i = 0; i < length; i++) {
      if (id == expand[i].nodeId) {
        index = i + 1;
        break;
      }
    }
    //插入
    expand.insertAll(index, tmp);
  }

  ///收起机构树:id代表被点击的机构id
  /// 做法是遍历整个expand列表,将直接和间接挂在该机构下面的节点标记,
  ///将这些被标记节点删除即可,此处用到的是将没有被标记的节点加入到新的列表中
  void _collect(int id) {
    //清楚之前的标记
    mark.clear();
    //标记
    _mark(id);
    //重新对expand赋值
    List tmp = new List();
    for (Node node in expand) {
      if (mark.indexOf(node.nodeId) < 0) {
        tmp.add(node);
      } else {
        node.expand = false;
      }
    }
    expand.clear();
    expand.addAll(tmp);
    setState(() {});
  }

  ///标记,在收起机构树的时候用到
  void _mark(int id) {
    for (Node node in expand) {
      if (id == node.fatherId) {
        if (node.isHasChildren) {
          _mark(node.nodeId);
        }
        mark.add(node.nodeId);
      }
    }
  }

  void buildNode() {
    Node node = new Node(false, 1, 1, 0, '哈哈1', true);
    Node node1 = new Node(false, 1, 2, 0, '哈哈2', false);
    Node node2 = new Node(false, 1, 3, 0, '哈哈3', false);
    Node node3 = new Node(false, 1, 4, 0, '哈哈4', false);

    Node node4 = new Node(false, 3, 5, 1, '呵呵1', true);

    Node node5 = new Node(false, 6, 6, 5, 'geg2', false);
    expand.add(node);
    expand.add(node1);
    expand.add(node2);
    expand.add(node3);

    list.add(node);
    list.add(node1);
    list.add(node2);
    list.add(node3);
    list.add(node4);
    list.add(node5);

    print('创建数据:' + expand.length.toString());
  }
}

class ImageText extends StatelessWidget {
  double margin = 0;
  String str = '';
  bool isExpand = false;
  bool isHasChildren = false;

  ImageText(double margin, String str, bool isExpand, bool isHasChildren) {
    this.margin = margin;
    this.str = str;
    this.isExpand = isExpand;
    this.isHasChildren = isHasChildren;
    print('margin:' + margin.toString());
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      alignment: Alignment.centerLeft,
      decoration: BoxDecoration(color: Colors.greenAccent),
      width: double.infinity,
      height: 40,
      margin: EdgeInsets.only(left: margin),
      child: Row(
        children: [
          Visibility(
            visible: isHasChildren,
            child: Image.asset(isExpand
                ? 'images/arrow_down_gray1.png'
                : 'images/arrow_right_gray.png'),
          ),
          Text(
            str,
            style: TextStyle(fontSize: 17),
          )
        ],
      ),
    );
  }
}
class Node {
  bool expand; //是否展开
  int depth; //深度

  int nodeId; //id
  int fatherId; //父类id
  T object; //
  bool isHasChildren; //是否有孩子节点

  Node(this.expand, this.depth, this.nodeId, this.fatherId, this.object,
      this.isHasChildren);
}

你可能感兴趣的:(Flutter)