flutter_swipe_action_cell 2.2.0
flutter_swipe_action_cell: ^2.2.0 copied to clipboard
An awesome UI package incluing iOS style cell swipe action effect.You can use this package to implement iOS style tableView cell swipe action
example/lib/main.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swipe_action_cell/flutter_swipe_action_cell.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CupertinoButton.filled(
child: const Text('Enter new page'),
onPressed: () {
Navigator.push(context,
CupertinoPageRoute(builder: (c) => const SwipeActionPage()));
}),
),
);
}
}
class Model {
String id = UniqueKey().toString();
int index = 0;
@override
String toString() {
return index.toString();
}
}
class SwipeActionPage extends StatefulWidget {
const SwipeActionPage({Key? key}) : super(key: key);
@override
_SwipeActionPageState createState() => _SwipeActionPageState();
}
class _SwipeActionPageState extends State<SwipeActionPage> {
List<Model> list = List.generate(30, (index) {
return Model()..index = index;
});
late SwipeActionController controller;
@override
void initState() {
super.initState();
controller = SwipeActionController(selectedIndexPathsChangeCallback:
(changedIndexPaths, selected, currentCount) {
print(
'cell at ${changedIndexPaths.toString()} is/are ${selected ? 'selected' : 'unselected'} ,current selected count is $currentCount');
///I just call setState() to update simply in this example.
///But the whole page will be rebuilt.
///So when you are developing,you'd better update a little piece
///of UI sub tree for best performance....
setState(() {});
});
}
Widget bottomBar() {
return Container(
color: Colors.grey[200],
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: CupertinoButton.filled(
padding: const EdgeInsets.only(),
child: const Text('open cell at 2'),
onPressed: () {
controller.openCellAt(
index: 2, trailing: true, animated: true);
}),
),
const SizedBox(
width: 10,
),
Expanded(
child: CupertinoButton.filled(
padding: const EdgeInsets.only(),
child: const Text('switch edit mode'),
onPressed: () {
controller.toggleEditingMode();
}),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: bottomBar(),
appBar: CupertinoNavigationBar(
middle: CupertinoButton.filled(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
minSize: 0,
child: const Text('deselect all', style: TextStyle(fontSize: 22)),
onPressed: () {
controller.deselectAll();
}),
leading: CupertinoButton.filled(
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 10),
minSize: 0,
child: Text(
'delete cells (${controller.getSelectedIndexPaths().length})',
style: const TextStyle(color: Colors.white)),
onPressed: () {
///获取选取的索引集合
List<int> selectedIndexes = controller.getSelectedIndexPaths();
List<String> idList = [];
for (var element in selectedIndexes) {
idList.add(list[element].id);
}
///遍历id集合,并且在原来的list中删除这些id所对应的数据
for (var itemId in idList) {
list.removeWhere((element) {
return element.id == itemId;
});
}
///更新内部数据,这句话一定要写哦
controller.deleteCellAt(indexPaths: selectedIndexes);
setState(() {});
}),
trailing: CupertinoButton.filled(
minSize: 0,
padding: const EdgeInsets.all(10),
child: const Text('select all'),
onPressed: () {
controller.selectAll(dataLength: list.length);
}),
),
body: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: list.length,
itemBuilder: (context, index) {
return _item(context, index);
},
),
);
}
Widget _item(BuildContext ctx, int index) {
return SwipeActionCell(
controller: controller,
index: index,
// Required!
key: ValueKey(list[index]),
/// Animation default value below
// normalAnimationDuration: 400,
// deleteAnimationDuration: 400,
selectedForegroundColor: Colors.black.withAlpha(30),
trailingActions: [
SwipeAction(
title: "delete",
performsFirstActionWithFullSwipe: true,
nestedAction: SwipeNestedAction(title: "confirm"),
onTap: (handler) async {
await handler(true);
list.removeAt(index);
setState(() {});
}),
SwipeAction(title: "action2", color: Colors.grey, onTap: (handler) {}),
],
leadingActions: [
SwipeAction(
title: "delete",
onTap: (handler) async {
await handler(true);
list.removeAt(index);
setState(() {});
}),
SwipeAction(
title: "action3", color: Colors.orange, onTap: (handler) {}),
],
child: GestureDetector(
onTap: () {
ScaffoldMessenger.of(ctx).showSnackBar(const SnackBar(
content: Text(
'tap',
),
duration: Duration(seconds: 1),
));
},
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Text("This is index of ${list[index]}",
style: const TextStyle(fontSize: 25)),
),
),
);
}
}