Flutter多选范围选择插件multiselect_scope的使用
Flutter多选范围选择插件multiselect_scope的使用
multiselect_scope
这是一个用于多个选择和跟踪选定项(全选、清除、反转选择等)的包。
使用方法
1. 创建 MultiselectController
如果您需要在MultiselectScope
外部管理选择,则创建MultiselectController
。
final multiselectController = MultiselectController();
2. 包装多子组件
将您的多子组件(如ListView
或GridView
或其他)包装在MultiselectScope
中。将域对象列表(例如Cars
或Employees
)传递给dataSource
。不要忘记为泛型参数传递域类型(如果域类型是String
,则为MultiselectScope<String>
)。现在让我们看看代码中的注释。
MultiselectScope<String>(
controller: multiselectController,
dataSource: items,
// 如果您希望用户点击返回按钮时自动清除选择,请将此设置为true
clearSelectionOnPop: true,
// 当您更新[dataSource]时,已选中的索引将更新
// 以便新[dataSource]中的相同元素仍然被选中
keepSelectedItemsBetweenUpdates: true,
initialSelectedIndexes: [1, 3],
// 在选择更改时调用的回调
onSelectionChanged: (indexes, items) {
// 处理选择变化逻辑
},
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
// 获取控制器链接
final controller = MultiselectScope.controllerOf(context);
final itemIsSelected = controller.isSelected(index);
return InkWell(
// 您可以根据需要实现选择逻辑
// 例如,在长按后开始选择模式
onLongPress: () {
if (!controller.selectionAttached) {
controller.select(index);
}
},
onTap: () {
if (controller.selectionAttached) {
controller.select(index);
}
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
// 根据是否选中来改变颜色
color: itemIsSelected ? Theme.of(context).primaryColor : null,
child: Text(
items[index],
style: TextStyle(fontSize: 22),
),
),
),
);
}),
)
3. 控制选择
获取作用域内的控制器链接:
final controller = MultiselectScope.controllerOf(context);
如果您想在作用域外部使用控制器,那么获取之前创建的链接(multiselectController
)
管理选择:
multiselectController.selectAll(); // 全选
multiselectController.select(0); // 选择第0项
multiselectController.invertSelection(); // 反转选择
multiselectController.clearSelection(); // 清除选择
multiselectController.setSelectedIndexes([1, 2, 3]); // 设置特定索引为选中状态
4. 获取已选项
final selectedItems = multiselectController.getSelectedItems().cast<String>();
或者检查项目是否被选中:
final itemIsSelected = controller.isSelected(index);
示例代码
下面是一个完整的示例代码,展示了如何使用multiselect_scope
进行多选操作。
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:multiselect_scope/multiselect_scope.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Multiselect Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Multiselect'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late List<String> _items;
late MultiselectController _multiselectController;
late Random random;
@override
void initState() {
super.initState();
random = Random();
_items = List.generate(10, (index) => 'Item $index');
_multiselectController = MultiselectController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
),
body: MultiselectScope<String>(
controller: _multiselectController,
dataSource: _items,
clearSelectionOnPop: true,
keepSelectedItemsBetweenUpdates: true,
initialSelectedIndexes: [1, 3],
onSelectionChanged: (indexes, items) {
debugPrint('Custom listener invoked! Indexes: $indexes Items: $items');
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
final controller = MultiselectScope.controllerOf(context);
final itemIsSelected = controller.isSelected(index);
return InkWell(
onLongPress: () {
if (!controller.selectionAttached) {
controller.select(index);
}
},
onTap: () {
debugPrint('Item is selected: $itemIsSelected');
if (controller.selectionAttached) {
controller.select(index);
}
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: itemIsSelected
? Theme.of(context).primaryColor
: null,
child: Text(
_items[index],
style: TextStyle(fontSize: 22),
),
),
),
);
}),
),
Wrap(
children: <Widget>[
RawMaterialButton(
child: Text('Add rand'),
padding: EdgeInsets.symmetric(horizontal: 8.0),
fillColor: Colors.blueGrey,
onPressed: () {
setState(() {
final randItem =
'RandItem' + random.nextInt(256).toString();
final randomIndex =
_items.isEmpty ? 0 : random.nextInt(_items.length);
_items.insert(randomIndex, randItem);
});
},
),
RawMaterialButton(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text('Remove rand'),
fillColor: Colors.lightGreen,
onPressed: () {
setState(() {
if (_items.length == 1) {
_items.removeAt(0);
} else {
_items.removeAt(random.nextInt(_items.length - 1));
}
});
},
),
RawMaterialButton(
padding: EdgeInsets.symmetric(horizontal: 8.0),
fillColor: Colors.blueGrey,
child: Text('Delete'),
onPressed: () {
setState(() {
final itemsToRemove = _multiselectController
.getSelectedItems()
.cast<String>();
_items = _items
.where(
(element) => !itemsToRemove.contains(element))
.toList();
});
},
),
RawMaterialButton(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text('Select 0'),
fillColor: Colors.lightGreen,
onPressed: () {
_multiselectController.select(0);
},
),
RawMaterialButton(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text('Select all'),
fillColor: Colors.amber,
onPressed: () {
_multiselectController.selectAll();
},
),
RawMaterialButton(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text('Invert'),
fillColor: Colors.tealAccent,
onPressed: () {
_multiselectController.invertSelection();
},
),
RawMaterialButton(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text('Clear'),
fillColor: Colors.deepPurpleAccent,
onPressed: () {
_multiselectController.clearSelection();
},
),
],
)
],
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
这个示例展示了如何在Flutter应用中使用multiselect_scope
插件来实现多选功能,并提供了添加、删除随机项、删除选中项、选择特定项、全选、反选和清空选择等功能。
更多关于Flutter多选范围选择插件multiselect_scope的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter多选范围选择插件multiselect_scope的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用multiselect_scope
插件来实现多选范围选择的代码示例。multiselect_scope
是一个用于实现多选功能的Flutter插件,特别适用于需要在列表中选择多个项目的情况。
首先,确保你已经在pubspec.yaml
文件中添加了multiselect_scope
的依赖:
dependencies:
flutter:
sdk: flutter
multiselect_scope: ^latest_version # 替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
以下是一个完整的示例代码,展示了如何使用multiselect_scope
插件:
import 'package:flutter/material.dart';
import 'package:multiselect_scope/multiselect_scope.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter MultiSelect Scope Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> items = List<String>.generate(20, (i) => "Item ${i + 1}");
List<String> selectedItems = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('MultiSelect Scope Demo'),
),
body: MultiSelectScope(
list: items,
selectedList: selectedItems,
itemBuilder: (context, index, isSelected) {
return Card(
child: ListTile(
leading: Checkbox(
value: isSelected,
onChanged: (newValue) {
setState(() {
if (newValue) {
selectedItems.add(items[index]);
} else {
selectedItems.remove(items[index]);
}
});
},
),
title: Text(items[index]),
),
);
},
onItemSelected: (index, isSelected) {
setState(() {
if (isSelected) {
selectedItems.add(items[index]);
} else {
selectedItems.remove(items[index]);
}
});
},
onRangeSelected: (startIndex, endIndex, isSelected) {
setState(() {
if (isSelected) {
for (int i = startIndex; i <= endIndex; i++) {
if (!selectedItems.contains(items[i])) {
selectedItems.add(items[i]);
}
}
} else {
for (int i = startIndex; i <= endIndex; i++) {
if (selectedItems.contains(items[i])) {
selectedItems.remove(items[i]);
}
}
}
});
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Selected Items'),
content: SingleChildScrollView(
child: ListBody(
children: selectedItems.map((item) => Text(item)).toList(),
),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
);
},
);
},
tooltip: 'Show Selected Items',
child: Icon(Icons.list),
),
);
}
}
解释
-
依赖添加:确保在
pubspec.yaml
中添加了multiselect_scope
依赖。 -
构建UI:
- 使用
Scaffold
构建基础页面结构。 - 使用
MultiSelectScope
包裹列表,MultiSelectScope
提供多选功能。 itemBuilder
用于构建每个列表项,这里使用Card
和ListTile
来展示每个项目,并在前面添加Checkbox
。onItemSelected
和onRangeSelected
用于处理单个项目和范围选择。
- 使用
-
显示选中的项目:
- 使用
FloatingActionButton
触发对话框显示选中的项目。
- 使用
这个示例展示了如何在Flutter中使用multiselect_scope
插件实现基本的多选功能。你可以根据需要进行进一步的自定义和扩展。