Flutter可检查树视图插件checkable_treeview的使用
Flutter可检查树视图插件checkable_treeview的使用
Checkable TreeView
Checkable TreeView 是一个用于 Flutter 的可选中和可定制的树形视图小部件。
Screenshot
Features
- 层次数据展示
- 节点选择支持多选
- 节点可展开/折叠
- 过滤和排序功能
- 自定义节点外观
- “全选”功能
- 全部展开/折叠节点选项
Getting Started
要在您的 Flutter 项目中使用 TreeView 小部件,请按照以下步骤操作:
flutter pub add checkable_treeview
Usage
以下是使用 TreeView 小部件的基本示例:
import 'package:flutter/material.dart';
import 'package:checkable_treeview/checkable_treeview.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('TreeView Example'),
),
body: TreeView<String>(
nodes: [
TreeNode(
label: const Text('Root'), // 根节点标签
value: 'root', // 根节点值
icon: Icon(Icons.folder), // 根节点图标
children: [
TreeNode(label: const Text('Child 1'), value: 'child1'), // 子节点1
TreeNode(label: const Text('Child 2'), value: 'child2'), // 子节点2
],
),
],
onSelectionChanged: (selectedValues) { // 当节点选择变化时触发
print('Selected values: $selectedValues');
},
),
),
);
}
}
Customization
TreeView 小部件提供了各种自定义选项:
showSelectAll
: 启用/禁用“全选”复选框selectAllWidget
: 自定义“全选”选项的小部件showExpandCollapseButton
: 显示/隐藏展开/折叠按钮initialExpandedLevels
: 设置初始展开级别数
有关更高级的自定义,请参阅 API 文档。
Advanced Features
Filtering
要实现过滤,使用 TreeViewState
的 filter
方法:
final treeViewKey = GlobalKey<TreeViewState<String>>();
treeViewKey.currentState?.filter('search keyword');
Sorting
要实现排序,使用 TreeViewState
的 sort
方法:
final treeViewKey = GlobalKey<TreeViewState<String>>();
treeViewKey.currentState?.sort((a, b) => a.label.compareTo(b.label));
Set Select All
要设置全选状态,使用 TreeViewState
的 setSelectAll
方法:
final treeViewKey = GlobalKey<TreeViewState<String>>();
treeViewKey.currentState?.setSelectAll(true);
Expand/Collapse All
要展开或折叠所有节点,使用 TreeViewState
的 expandAll
和 collapseAll
方法:
final treeViewKey = GlobalKey<TreeViewState<String>>();
treeViewKey.currentState?.expandAll();
treeViewKey.currentState?.collapseAll();
Get Selected Nodes
要获取选定的节点,使用 TreeViewState
的 getSelectedNodes
方法:
final treeViewKey = GlobalKey<TreeViewState<String>>();
final selectedNodes = treeViewKey.currentState?.getSelectedNodes();
Get Selected Values
要获取选定的值,使用 TreeViewState
的 getSelectedValues
方法:
final treeViewKey = GlobalKey<TreeViewState<String>>();
final selectedValues = treeViewKey.currentState?.getSelectedValues();
完整示例 Demo
下面是一个完整的示例,包含搜索、排序、全选等功能:
import 'package:flutter/material.dart';
import 'package:checkable_treeview/checkable_treeview.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'TreeView Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'TreeView Example'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
enum SortOrder { defaultOrder, ascending, descending }
class _MyHomePageState extends State<MyHomePage> {
List<TreeNode<String>> _nodes = [];
String _searchKeyword = '';
final TextEditingController _searchController = TextEditingController();
final _treeViewKey = GlobalKey<TreeViewState<String>>();
SortOrder _currentSortOrder = SortOrder.defaultOrder;
[@override](/user/override)
void initState() {
super.initState();
_nodes = [
TreeNode(
label: const Text('Project Folder'),
value: 'project_folder',
trailing: (context, node) {
return Text(
'(${_treeViewKey.currentState?.getChildSelectedValues(node).length} selected)');
},
children: [
TreeNode(
label: const Text('src'),
icon: Icon(Icons.folder_open),
children: [
TreeNode(
label: const Text('main.js'),
value: 'main_js',
icon: Icon(Icons.javascript),
isSelected: true),
TreeNode(
label: const Text('app.js'),
value: 'app_js',
icon: Icon(Icons.javascript)),
TreeNode(
label: const Text('styles.css'),
value: 'styles_css',
icon: Icon(Icons.css)),
],
),
TreeNode(
label: const Text('public'),
value: 'public_folder',
icon: Icon(Icons.folder_open),
children: [
TreeNode(
label: const Text('index.html'),
value: 'index_html',
icon: Icon(Icons.html)),
TreeNode(
label: const Text('favicon.ico'),
value: 'favicon',
icon: Icon(Icons.image)),
],
),
],
),
TreeNode(
label: const Text('Config Files'),
value: 'config_folder',
children: [
TreeNode(
label: const Text('package.json'),
value: 'package_json',
icon: Icon(Icons.settings)),
TreeNode(
label: const Text('.gitignore'),
value: 'gitignore',
icon: Icon(Icons.remove_red_eye),
trailing: (context, node) {
return Text(node.data as String);
},
data: '1 KB',
),
],
),
];
}
void _onSelectionChanged(List<String?> selectedValues) {
print('Selected node values: $selectedValues');
}
bool _filterNode(TreeNode<String> node) {
if (_searchKeyword.isEmpty) {
return true;
}
return node.value?.toLowerCase().contains(_searchKeyword.toLowerCase()) ??
false;
}
void _performSearch() {
setState(() {
_searchKeyword = _searchController.text;
_treeViewKey.currentState?.filter(_filterNode);
});
_printSelectedNodes();
}
void _sortNodes(SortOrder order) {
setState(() {
_currentSortOrder = order;
switch (order) {
case SortOrder.defaultOrder:
_treeViewKey.currentState?.sort(null);
break;
case SortOrder.ascending:
_treeViewKey.currentState
?.sort((a, b) => (a.value ?? '').compareTo(b.value ?? ''));
break;
case SortOrder.descending:
_treeViewKey.currentState
?.sort((a, b) => (b.value ?? '').compareTo(a.value ?? ''));
break;
}
});
}
void _expandAll() {
_treeViewKey.currentState?.expandAll();
}
void _collapseAll() {
_treeViewKey.currentState?.collapseAll();
}
void _printSelectedNodes() {
List<TreeNode<String>> selectedNodes =
_treeViewKey.currentState?.getSelectedNodes() ?? [];
print('Selected nodes:');
for (var node in selectedNodes) {
print('Value: ${node.value}, Label: ${node.label}');
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _searchController,
decoration: const InputDecoration(
hintText: 'Enter search keyword',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: _performSearch,
child: const Text('Search'),
),
const SizedBox(width: 8),
SizedBox(
width: 150, // 设置固定宽度
child: DropdownButton<SortOrder>(
isExpanded: true,
value: _currentSortOrder,
onChanged: (SortOrder? newValue) {
if (newValue != null) {
_sortNodes(newValue);
}
},
items: SortOrder.values.map((SortOrder order) {
return DropdownMenuItem<SortOrder>(
value: order,
child: Text(_getSortOrderText(order)),
);
}).toList(),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton(
onPressed: _expandAll,
child: const Text('Expand All'),
),
ElevatedButton(
onPressed: _collapseAll,
child: const Text('Collapse All'),
),
ElevatedButton(
onPressed: () {
_treeViewKey.currentState?.setSelectAll(true);
},
child: const Text('全部选中'),
),
ElevatedButton(
onPressed: () {
_treeViewKey.currentState?.setSelectAll(false);
},
child: const Text('Deselect All'),
),
ElevatedButton(
onPressed: _printSelectedNodes,
child: const Text('Print Selected Nodes'),
),
],
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TreeView<String>(
key: _treeViewKey,
nodes: _nodes,
onSelectionChanged: _onSelectionChanged,
initialExpandedLevels: 1,
showSelectAll: true,
selectAllWidget: const Text('Select All'),
selectAllTrailing: (context) {
return Text(
'(${_treeViewKey.currentState?.getSelectedNodes().length} selected)');
},
showExpandCollapseButton: true,
),
),
),
],
),
);
}
String _getSortOrderText(SortOrder order) {
switch (order) {
case SortOrder.defaultOrder:
return 'Default Order';
case SortOrder.ascending:
return 'Ascending';
case SortOrder.descending:
return 'Descending';
}
}
[@override](/user/override)
void dispose() {
_searchController.dispose();
super.dispose();
}
}
更多关于Flutter可检查树视图插件checkable_treeview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter可检查树视图插件checkable_treeview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用checkable_treeview
插件来创建一个可检查的树视图的示例代码。checkable_treeview
是一个Flutter包,用于显示可检查的树结构。
首先,确保你已经在pubspec.yaml
文件中添加了checkable_treeview
依赖:
dependencies:
flutter:
sdk: flutter
checkable_treeview: ^最新版本号 # 请替换为实际最新版本号
然后运行flutter pub get
来获取依赖。
接下来,在你的Flutter项目中,你可以按照以下方式使用checkable_treeview
:
import 'package:flutter/material.dart';
import 'package:checkable_treeview/checkable_treeview.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Checkable Treeview Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Checkable Treeview Demo'),
),
body: CheckableTreeViewDemo(),
),
);
}
}
class CheckableTreeViewDemo extends StatefulWidget {
@override
_CheckableTreeViewDemoState createState() => _CheckableTreeViewDemoState();
}
class _CheckableTreeViewDemoState extends State<CheckableTreeViewDemo> {
final List<CheckableNode> nodes = [
CheckableNode(
title: 'Parent 1',
children: [
CheckableNode(title: 'Child 1.1'),
CheckableNode(title: 'Child 1.2'),
],
),
CheckableNode(
title: 'Parent 2',
children: [
CheckableNode(
title: 'Child 2.1',
children: [
CheckableNode(title: 'Grandchild 2.1.1'),
CheckableNode(title: 'Grandchild 2.1.2'),
],
),
CheckableNode(title: 'Child 2.2'),
],
),
];
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: CheckableTreeView(
nodes: nodes,
onChanged: (List<CheckableNode> checkedNodes) {
// 处理选中的节点
print('Checked nodes: $checkedNodes');
},
),
);
}
}
在这个示例中:
- 我们定义了一个包含树节点的列表
nodes
,其中每个节点都是一个CheckableNode
对象。 CheckableNode
对象包含标题(title
)和子节点列表(children
)。- 在
CheckableTreeViewDemo
组件中,我们使用CheckableTreeView
小部件来显示树视图,并传入节点列表。 - 当树中的节点被选中或取消选中时,
onChanged
回调会被触发,并传递当前选中的节点列表。
这个示例展示了如何使用checkable_treeview
包来创建一个简单的可检查树视图。你可以根据需要进一步自定义和扩展这个示例。