Flutter分组展开折叠插件grouped_expansion_tile的使用
Flutter分组展开折叠插件grouped_expansion_tile的使用
特性
这个小部件用于展示带有展开折叠功能的分组数据。
简单用法
设置 data
和 builder
属性。data
必须是一个扩展了 GroupBase
类的对象。如果你不需要额外的属性,可以直接使用 GroupBase
类。builder
会分配给展开折叠小部件的标题属性。
class Category extends GroupBase {
String additional;
Category({
required this.additional,
required String uid,
String? parent,
}) : super(uid: uid, parent: parent);
}
List<Category> _createList() {
final topParents = List.generate(10,
(index) => Category(additional: "auto-generated-$index", uid: "2$index"));
return [
Category(additional: "group-1", uid: "1"),
Category(additional: "group-2", uid: "2"),
Category(additional: "group-1-1", uid: "3", parent: "1"),
Category(additional: "group-2-1", uid: "4", parent: "2"),
Category(additional: "group-3", uid: "5"),
Category(additional: "group-2-1-1", uid: "6", parent: "4"),
Category(additional: "group-2-2", uid: "7", parent: "2"),
Category(additional: "group-2-3", uid: "8", parent: "2"),
Category(additional: "group-2-1-1-1", uid: "9", parent: "6"),
Category(additional: "group-2-1-1-2", uid: "10", parent: "6"),
...topParents,
];
}
final groupedExpansionTile = GroupedExpansionTile<Category>(
data: _createList(),
builder: (parent, depth) => Text(parent.self.additional),
);
return Scaffold(
appBar: AppBar(
title: const Text("Simplest"),
),
body: groupedExpansionTile,
);
启用拖拽手势
你可以使每个项目都可以被拖动。将 draggable
属性设为 true
以启用拖拽。你可以指定自己的边框来高亮目标小部件,当它接受拖动项时。当目标项接受拖动项时,onAccept
会被调用。你可以在那里编写自己的处理逻辑,例如更新项目列表。
final List<Category> _data = _createList();
GroupedExpansionTile<Category>(
data: _data,
builder: (parent, depth) => Text(parent.self.additional),
childIndent: 50,
controlAffinity: ListTileControlAffinity.trailing,
initialBorder: Border.all(color: Colors.orange, width: 1),
highlightedBorder:
Border.all(color: Colors.deepPurple.shade800, width: 3),
initiallyExpanded: false,
draggable: true,
onAccept: (source, dest) async {
setState(() {
// source 是 _data 中的一个元素
source.self.parent = dest?.uid;
});
},
onExpansionChanged: (expanded, parent, depth) {
setState(() {
parent.self.additional += "@";
});
},
padding: EdgeInsets.zero,
);
已知问题
- 当拖动第三级项目时,顶级项目会接受被拖动的项目,只要拖动位置在小部件内。它应该只在被拖动的位置在已折叠的父区域时接受被拖动的项目。
完整示例Demo
import 'package:flutter/material.dart';
import 'package:grouped_expansion_tile/grouped_expansion_tile.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// 这个小部件是你的应用的根
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const GroupedExtensionTileSample(),
);
}
}
class Category extends GroupBase {
String additional;
Category({
required this.additional,
required String uid,
String? parent,
}) : super(uid: uid, parent: parent);
}
List<Category> _createList() {
final topParents = List.generate(10,
(index) => Category(additional: "auto-generated-$index", uid: "2$index"));
return [
Category(additional: "group-1", uid: "1"),
Category(additional: "group-2", uid: "2"),
Category(additional: "group-1-1", uid: "3", parent: "1"),
Category(additional: "group-2-1", uid: "4", parent: "2"),
Category(additional: "group-3", uid: "5"),
Category(additional: "group-2-1-1", uid: "6", parent: "4"),
Category(additional: "group-2-2", uid: "7", parent: "2"),
Category(additional: "group-2-3", uid: "8", parent: "2"),
Category(additional: "group-2-1-1-1", uid: "9", parent: "6"),
Category(additional: "group-2-1-1-2", uid: "10", parent: "6"),
...topParents,
];
}
Future<void> _showDialog(
BuildContext context,
String title,
String text,
) async {
final alert = AlertDialog(
title: Text(title),
content: Text(text),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("OK"),
),
],
);
await showDialog(
context: context,
builder: (BuildContext context) => alert,
);
}
class GroupedExtensionTileSample extends StatelessWidget {
const GroupedExtensionTileSample({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: const Text("Grouped Extension Sample"),
),
body: PageView(
children: [
_createSimplestSample(),
const GroupedExtensionTileSample2(),
],
),
),
);
}
Widget _createSimplestSample() {
final groupedExpansionTile = GroupedExpansionTile<Category>(
data: _createList(),
builder: (parent, depth) => Text(parent.self.additional),
);
return Scaffold(
appBar: AppBar(
title: const Text("Simplest"),
),
body: groupedExpansionTile,
);
}
}
class GroupedExtensionTileSample2 extends StatefulWidget {
const GroupedExtensionTileSample2({Key? key}) : super(key: key);
[@override](/user/override)
_GroupedExtensionTileSample2 createState() => _GroupedExtensionTileSample2();
}
class _GroupedExtensionTileSample2 extends State<GroupedExtensionTileSample2> {
final List<Category> _data = _createList();
[@override](/user/override)
Widget build(BuildContext context) {
final groupedExpansionTile = GroupedExpansionTile<Category>(
data: _data,
builder: (parent, depth) => Text(parent.self.additional),
childIndent: 50,
controlAffinity: ListTileControlAffinity.trailing,
initialBorder: Border.all(color: Colors.orange, width: 1),
highlightedBorder:
Border.all(color: Colors.deepPurple.shade800, width: 3),
initiallyExpanded: false,
draggable: true,
onAccept: (source, dest) async {
setState(() {
// source 是 _data 中的一个元素
source.self.parent = dest?.uid;
});
},
onExpansionChanged: (expanded, parent, depth) {
setState(() {
parent.self.additional += "@";
});
},
padding: EdgeInsets.zero,
);
return Scaffold(
appBar: AppBar(
title: const Text("Advanced"),
),
body: groupedExpansionTile,
);
}
}
更多关于Flutter分组展开折叠插件grouped_expansion_tile的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter分组展开折叠插件grouped_expansion_tile的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用grouped_expansion_tile
插件来实现分组展开和折叠功能的代码示例。grouped_expansion_tile
是一个第三方包,用于在Flutter应用中创建分组可折叠的列表项。
首先,确保你已经在pubspec.yaml
文件中添加了grouped_expansion_tile
依赖:
dependencies:
flutter:
sdk: flutter
grouped_expansion_tile: ^latest_version # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
以下是一个完整的示例代码,展示如何使用grouped_expansion_tile
:
import 'package:flutter/material.dart';
import 'package:grouped_expansion_tile/grouped_expansion_tile.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Grouped Expansion Tile Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> groupTitles = ['Group 1', 'Group 2', 'Group 3'];
final Map<String, List<String>> groupItems = {
'Group 1': ['Item 1.1', 'Item 1.2', 'Item 1.3'],
'Group 2': ['Item 2.1', 'Item 2.2'],
'Group 3': ['Item 3.1', 'Item 3.2', 'Item 3.3', 'Item 3.4'],
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Grouped Expansion Tile Demo'),
),
body: ListView.separated(
itemCount: groupTitles.length,
separatorBuilder: (_, __) => Divider(),
itemBuilder: (_, index) {
final String groupTitle = groupTitles[index];
final List<String> items = groupItems[groupTitle]!;
return GroupedExpansionTile(
title: Text(groupTitle),
children: List.generate(
items.length,
(subIndex) {
return ListTile(
title: Text(items[subIndex]),
);
},
),
);
},
),
);
}
}
代码解释
- 依赖导入:首先导入
grouped_expansion_tile
包。 - 主应用:创建一个
MyApp
类作为应用入口,它包含一个MaterialApp
。 - 主页:
MyHomePage
是一个有状态的Widget,它持有分组标题和分组项的数据。 - 数据准备:定义了两个列表,
groupTitles
存储分组标题,groupItems
是一个映射,存储每个分组下的子项。 - 构建UI:在
build
方法中,使用ListView.separated
来创建一个列表视图,每个列表项是一个GroupedExpansionTile
。 - GroupedExpansionTile:每个
GroupedExpansionTile
的标题由groupTitles
提供,子项由groupItems
提供,并生成相应的ListTile
。
运行这段代码,你将看到一个包含多个可折叠分组的列表,每个分组标题点击后可以展开或折叠其下的子项。
希望这个示例对你有帮助!如果你有任何其他问题,请随时提问。