Flutter树形列表展示插件tree_list的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter树形列表展示插件tree_list的使用

Tree View 是一个功能强大且高度可定制的Flutter包,用于展示树形结构的数据。该插件支持声音空安全,并且是从 tree_view 包分叉而来。

安装

在您的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  tree_view: ^0.0.5

然后运行以下命令来获取依赖:

flutter packages get

示例

假设我们想要展示如下结构的树形视图:

Desktop
|-- documents
|   |-- Resume.docx
|   |-- Billing-Info.docx
|-- MeetingReport.xls
|-- MeetingReport.pdf
|-- Demo.zip

在这个例子中:

  1. Resume.docxBilling-Info.docxdocuments 的子节点。
  2. documents, MeetingReport.xls, MeetingReport.pdfDemo.zip 都是 Desktop 的子节点。

以下是对应的 TreeView 实现代码:

var treeView = TreeView(
  parentList: [
    Parent(
      parent: Text('Desktop'),
      childList: ChildList(
        children: <Widget>[
          Parent(
            parent: Text('documents'),
            childList: ChildList(
              children: <Widget>[
                Text('Resume.docx'),
                Text('Billing-Info.docx'),
              ],
            ),
          ),
          Text('MeetingReport.xls'),
          Text('MeetingReport.pdf'),
          Text('Demo.zip'),
        ],
      ),
    ),
  ],
);

完整示例 Demo

下面是一个更完整的示例,展示了如何使用 TreeView 插件来构建一个文件系统树状结构。

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

void main() => runApp(MainApplication());

class MainApplication extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class Document {
  final String name;
  final DateTime dateModified;
  final bool isFile;
  final List<Document> childData;

  Document({
    this.name,
    this.dateModified,
    this.isFile = false,
    this.childData = const [],
  });
}

class DirectoryWidget extends StatelessWidget {
  final String directoryName;
  final DateTime lastModified;

  DirectoryWidget({this.directoryName, this.lastModified});

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(directoryName),
      subtitle: Text('Last Modified: ${lastModified.toString()}'),
    );
  }
}

class FileWidget extends StatelessWidget {
  final String fileName;
  final DateTime lastModified;

  FileWidget({this.fileName, this.lastModified});

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(fileName),
      subtitle: Text('Last Modified: ${lastModified.toString()}'),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Document> documentList = [
    Document(
      name: 'Desktop',
      dateModified: DateTime.now(),
      childData: [
        Document(name: 'Projects', dateModified: DateTime.now(), childData: [
          Document(
              name: 'flutter_app',
              dateModified: DateTime.now(),
              childData: [
                Document(
                  name: 'README.md',
                  dateModified: DateTime.now(),
                  isFile: true,
                ),
                Document(
                  name: 'pubspec.yaml',
                  dateModified: DateTime.now(),
                  isFile: true,
                ),
                // 更多文件...
              ]),
        ]),
        Document(
          name: 'test.sh',
          dateModified: DateTime.now(),
          isFile: true,
        ),
        // 更多文件和目录...
      ],
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Tree View demo'),
      ),
      body: TreeView(
        startExpanded: false,
        children: _getChildList(documentList),
      ),
    );
  }

  List<Widget> _getChildList(List<Document> childDocuments) {
    return childDocuments.map((document) {
      if (!document.isFile) {
        return Container(
          margin: EdgeInsets.only(left: 8),
          child: TreeViewChild(
            parent: _getDocumentWidget(document: document),
            children: _getChildList(document.childData),
          ),
        );
      }
      return Container(
        margin: const EdgeInsets.only(left: 4.0),
        child: _getDocumentWidget(document: document),
      );
    }).toList();
  }

  Widget _getDocumentWidget({@required Document document}) =>
      document.isFile ? _getFileWidget(document: document) : _getDirectoryWidget(document: document);

  DirectoryWidget _getDirectoryWidget({@required Document document}) => DirectoryWidget(
        directoryName: document.name,
        lastModified: document.dateModified,
      );

  FileWidget _getFileWidget({@required Document document}) => FileWidget(
        fileName: document.name,
        lastModified: document.dateModified,
      );
}

此示例演示了如何创建一个包含文件和目录的树形视图,并展示了如何根据数据动态生成树形结构。


更多关于Flutter树形列表展示插件tree_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter树形列表展示插件tree_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用tree_list插件来展示树形列表的一个基本示例。假设你已经将tree_list插件添加到了你的pubspec.yaml文件中。

首先,确保你的pubspec.yaml文件中包含以下依赖项:

dependencies:
  flutter:
    sdk: flutter
  tree_list: ^最新版本号  # 请替换为实际可用的最新版本号

然后,运行flutter pub get来安装依赖项。

接下来,你可以在你的Flutter项目中创建一个树形列表。以下是一个简单的示例代码:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tree List Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Tree List Example'),
        ),
        body: TreeListExample(),
      ),
    );
  }
}

class TreeListExample extends StatelessWidget {
  // 示例树形结构数据
  final List<TreeNode> treeData = [
    TreeNode(
      title: 'Node 1',
      children: [
        TreeNode(title: 'Child 1.1'),
        TreeNode(
          title: 'Child 1.2',
          children: [
            TreeNode(title: 'Grandchild 1.2.1'),
            TreeNode(title: 'Grandchild 1.2.2'),
          ],
        ),
      ],
    ),
    TreeNode(
      title: 'Node 2',
      children: [
        TreeNode(title: 'Child 2.1'),
        TreeNode(title: 'Child 2.2'),
      ],
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: TreeList(
        treeData: treeData,
        nodeBuilder: (context, node) {
          return ListTile(
            title: Text(node.title),
            trailing: Icon(
              node.expanded ? Icons.expand_more : Icons.chevron_right,
            ),
            onTap: () {
              // 切换节点的展开/折叠状态
              node.toggleExpanded();
            },
          );
        },
        childNodeBuilder: (context, node, child) {
          return Padding(
            padding: const EdgeInsets.only(left: 16.0),
            child: ListTile(
              title: Text(child.title),
            ),
          );
        },
      ),
    );
  }
}

// TreeNode 类定义(假设tree_list插件没有自带,需要自定义)
class TreeNode {
  String title;
  List<TreeNode> children;
  bool expanded = false;

  TreeNode({required this.title, this.children = const []});

  void toggleExpanded() {
    expanded = !expanded;
  }
}

说明:

  1. TreeNode 类:这个类定义了树形结构的节点,包括节点的标题、子节点列表以及节点的展开/折叠状态。注意,这个类是基于假设tree_list插件没有自带TreeNode类而自定义的。如果插件自带了类似的数据结构,你应该使用插件提供的类。

  2. TreeListExample 类:这个类构建了一个简单的树形列表。它使用TreeList组件,并定义了nodeBuilderchildNodeBuilder两个构建器函数来构建节点和子节点的UI。

  3. TreeList 组件:这个组件接收树形结构的数据(treeData),并使用提供的构建器函数来渲染节点和子节点。

  4. 交互:当用户点击节点时,会调用toggleExpanded方法来切换节点的展开/折叠状态。

请注意,这个示例代码是基于假设tree_list插件的API类似于上述用法。如果tree_list插件的实际API有所不同,请查阅插件的官方文档并进行相应的调整。

回到顶部