Flutter嵌套选择列表插件nested_choice_list的使用
Flutter嵌套选择列表插件nested_choice_list的使用
安装
首先,你需要在 pubspec.yaml
文件中添加依赖项:
dependencies:
nested_choice_list: latest_version
然后运行 flutter pub get
来安装包。
示例代码
下面是一个完整的示例代码,展示了如何使用 NestedChoiceList
插件来创建一个嵌套的选择列表界面。这个示例包括了单选模式和多选模式,并且提供了回调函数来处理用户的选择操作。
import 'package:flutter/material.dart';
import 'package:nested_choice_list/nested_choice_list.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'NestedChoiceList Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
// Home page
class HomePage extends StatefulWidget {
const HomePage({super.key});
[@override](/user/override)
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool showSelectedItems = true;
bool enableSelectAll = true;
bool showNavigationPath = false;
bool enableMultiSelect = false;
bool enableSearch = false;
NestedChoiceEntity? selectedItem;
List<NestedChoiceEntity>? selectedItems;
final items = const [
NestedChoiceEntity(
value: 'value1',
label: 'label1 level1',
children: [
NestedChoiceEntity(value: 'value2', label: 'label2 level 2'),
NestedChoiceEntity(value: 'value3', label: 'label3 level 2'),
NestedChoiceEntity(
value: 'value4',
label: 'label4 level 2',
children: [
NestedChoiceEntity(value: 'value2', label: 'label2 level 3'),
NestedChoiceEntity(value: 'value3', label: 'label3 level 3'),
NestedChoiceEntity(
value: 'value4',
label: 'label4 level 3',
children: [
NestedChoiceEntity(value: 'value2', label: 'label2 level 4'),
NestedChoiceEntity(value: 'value3', label: 'label3 level 4'),
NestedChoiceEntity(value: 'value4', label: 'label4 level 4'),
],
),
],
),
],
),
NestedChoiceEntity(
value: 'value2',
label: 'label2 level1',
children: [
NestedChoiceEntity(value: 'value2', label: 'label2 level 2'),
NestedChoiceEntity(value: 'value3', label: 'label3 level 2'),
NestedChoiceEntity(
value: 'value4',
label: 'label4 level 2',
children: [
NestedChoiceEntity(value: 'value2', label: 'label2 level 3'),
NestedChoiceEntity(value: 'value3', label: 'label3 level 3'),
NestedChoiceEntity(value: 'value4', label: 'label4 level 3'),
],
),
],
),
NestedChoiceEntity(
value: 'value3',
label: 'label3 level1',
children: [
NestedChoiceEntity(value: 'value2', label: 'label2 level 2'),
NestedChoiceEntity(value: 'value3', label: 'label3 level 2'),
NestedChoiceEntity(value: 'value4', label: 'label4 level 2'),
],
),
NestedChoiceEntity(value: 'value4', label: 'label4 level1'),
];
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('NestedChoiceList'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CheckboxListTile.adaptive(
title: const Text('ShowNavigationPath'),
value: showNavigationPath,
onChanged: (newValue) {
setState(() {
showNavigationPath = newValue ?? false;
});
},
),
const Divider(),
CheckboxListTile.adaptive(
title: const Text('EnableMultiSelect'),
value: enableMultiSelect,
onChanged: (newValue) {
setState(() {
enableMultiSelect = newValue ?? false;
});
},
),
const Divider(),
CheckboxListTile.adaptive(
title: const Text('EnableSelectAll'),
value: enableSelectAll,
onChanged: (newValue) {
setState(() {
enableSelectAll = newValue ?? false;
});
},
),
const Divider(),
CheckboxListTile.adaptive(
title: const Text('ShowSelectedItems'),
value: showSelectedItems,
onChanged: (newValue) {
setState(() {
showSelectedItems = newValue ?? false;
});
},
),
const Divider(),
CheckboxListTile.adaptive(
title: const Text('EnableSearch'),
value: enableSearch,
onChanged: (newValue) {
setState(() {
enableSearch = newValue ?? false;
});
},
),
const Divider(),
ElevatedButton(
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => DemoOf NestedChoiceList(
items: items,
showSelectedItems: showSelectedItems,
enableSelectAll: enableSelectAll,
showNavigationPath: showNavigationPath,
enableMultiSelect: enableMultiSelect,
enableSearch: enableSearch,
),
),
);
if (result is NestedChoiceEntity) {
setState(() {
selectedItem = result;
selectedItems = null;
});
} else if (result is List<NestedChoiceEntity>) {
setState(() {
selectedItem = null;
selectedItems = result;
});
}
},
child: const Text(
'Show Demo',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
const Divider(),
const Text(
'⇩ Result ⇩',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
const SizedBox(
height: 20,
),
if (selectedItem != null)
Text(
'onTapItem: ${selectedItem!.label}',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
),
if (selectedItems != null)
Text(
'onSelectionChange: $selectedItems',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.orange,
),
)
],
),
),
),
);
}
}
class Demo of NestedChoiceList extends StatelessWidget {
const Demo of NestedChoiceList({
required this.items,
super.key,
required this.showSelectedItems,
required this.enableSelectAll,
required this.showNavigationPath,
required this.enableMultiSelect,
required this.enableSearch,
});
final List<NestedChoiceEntity> items;
final bool showSelectedItems;
final bool enableSelectAll;
final bool showNavigationPath;
final bool enableMultiSelect;
final bool enableSearch;
[@override](/user/override)
Widget build(BuildContext context) {
List<NestedChoiceEntity> selectedItems = [];
return Scaffold(
appBar: AppBar(
title: const Text('Demo'),
),
body: NestedChoiceList(
items: items,
showSelectedItems: showSelectedItems,
enableSelectAll: enableSelectAll,
showNavigationPath: showNavigationPath,
enableMultiSelect: enableMultiSelect,
enableSearch: enableSearch,
style: const NestedListStyle(),
onTapItem: (item) {
debugPrint('onTapItem -> $item');
Navigator.of(context).pop(item);
},
onSelectionChange: (items) {
debugPrint('onSelectionChange -> $items');
selectedItems = items;
},
onNavigationChange: (pageIndex) {
debugPrint('onNavigationChange -> pageIndex: $pageIndex');
},
),
bottomNavigationBar: enableMultiSelect
? SafeArea(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop(selectedItems);
},
child: const Text('Confirm selected items'),
),
)
: null,
);
}
}
更多关于Flutter嵌套选择列表插件nested_choice_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter嵌套选择列表插件nested_choice_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用nested_choice_list
插件来实现嵌套选择列表的示例代码。请注意,由于nested_choice_list
并非一个官方或广泛认可的Flutter插件(在撰写此回复时),我假设这是一个自定义或第三方插件,并且以下示例代码是基于一般嵌套列表选择逻辑的假设实现。如果你使用的插件有特定的API或方法,请参考其官方文档进行调整。
首先,确保你已经在pubspec.yaml
文件中添加了nested_choice_list
(或相应的插件名称,如果它存在的话):
dependencies:
flutter:
sdk: flutter
nested_choice_list: ^x.y.z # 替换为实际的版本号
然后,运行flutter pub get
来安装依赖。
接下来,是一个示例代码,展示如何使用一个假设的NestedChoiceList
组件来实现嵌套选择列表:
import 'package:flutter/material.dart';
import 'package:nested_choice_list/nested_choice_list.dart'; // 假设的插件导入
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Nested Choice List Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: NestedChoiceListScreen(),
);
}
}
class NestedChoiceListScreen extends StatefulWidget {
@override
_NestedChoiceListScreenState createState() => _NestedChoiceListScreenState();
}
class _NestedChoiceListScreenState extends State<NestedChoiceListScreen> {
// 假设的数据结构
final List<ChoiceItem> choices = [
ChoiceItem(
id: '1',
title: 'Category 1',
children: [
ChoiceItem(id: '1-1', title: 'Subcategory 1-1'),
ChoiceItem(id: '1-2', title: 'Subcategory 1-2'),
],
),
ChoiceItem(
id: '2',
title: 'Category 2',
children: [
ChoiceItem(id: '2-1', title: 'Subcategory 2-1'),
ChoiceItem(
id: '2-2',
title: 'Subcategory 2-2',
children: [
ChoiceItem(id: '2-2-1', title: 'Sub-subcategory 2-2-1'),
],
),
],
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Nested Choice List Demo'),
),
body: NestedChoiceList(
choices: choices,
onSelectionChanged: (selectedItems) {
// 处理选择变更
print('Selected items: $selectedItems');
},
),
);
}
}
// 假设的ChoiceItem类,用于表示列表项
class ChoiceItem {
final String id;
final String title;
final List<ChoiceItem>? children;
ChoiceItem({required this.id, required this.title, this.children});
}
// 假设的NestedChoiceList组件(实际上你应该使用插件提供的组件)
class NestedChoiceList extends StatefulWidget {
final List<ChoiceItem> choices;
final ValueChanged<List<String>> onSelectionChanged;
NestedChoiceList({required this.choices, required this.onSelectionChanged});
@override
_NestedChoiceListState createState() => _NestedChoiceListState();
}
class _NestedChoiceListState extends State<NestedChoiceList> {
// 省略了实际的实现细节,因为这取决于插件的具体API
// 以下是一个简化的逻辑示例,用于说明如何处理选择
List<String> _selectedItems = [];
void _handleItemTap(ChoiceItem item) {
setState(() {
if (_selectedItems.contains(item.id)) {
_selectedItems.remove(item.id);
} else {
_selectedItems.add(item.id);
}
widget.onSelectionChanged(_selectedItems);
});
}
@override
Widget build(BuildContext context) {
// 实际的构建逻辑取决于插件的API,这里仅展示一个概念性的实现
return ListView.builder(
itemCount: widget.choices.length,
itemBuilder: (context, index) {
final item = widget.choices[index];
return ListTile(
title: Text(item.title),
trailing: Checkbox(
value: _selectedItems.contains(item.id),
onChanged: (value) {
_handleItemTap(item);
// 注意:对于真正的嵌套列表,这里需要递归处理子项
},
),
onTap: () => _handleItemTap(item), // 处理点击事件
);
// 注意:这里省略了子项的处理逻辑,真正的实现需要递归渲染子项
},
);
}
}
注意:上述代码是一个简化的示例,用于说明概念。真正的nested_choice_list
插件(如果存在)可能会有不同的API和组件使用方式。你应该查阅该插件的官方文档来了解如何正确使用它。如果插件不存在,你可能需要自己实现一个嵌套选择列表组件,或者寻找一个合适的第三方库。