左滑删除效果分为两个部分:一部分是“向左滑动出现删除”的控件,这个控件可以通过水平滑动进行平移;另一部分是删除按钮,这个控件默认是不显示的,当用户向左滑动时随之显示。
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
String _storageDir = '';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SlideDelete(),
);
}
}
class Slide extends StatefulWidget {
// Key key;
List<Widget> actions;
Widget child;
double actionsWidth;
Slide(
// this.key,
@required this.child,
@required this.actionsWidth,
@required this.actions,
);
@override
State<StatefulWidget> createState() {
return _Slide();
throw UnimplementedError();
}
}
class _Slide extends State<Slide> with TickerProviderStateMixin {
double translateX = 0;
AnimationController animationController;
@override
void initState() {
super.initState();
animationController = AnimationController(
lowerBound: -widget.actionsWidth,
upperBound: 0,
vsync: this,
duration: Duration(milliseconds: 300)
)..addListener(() {
translateX = animationController.value;
setState(() {
});
});
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned.fill(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: widget.actions,
)),
GestureDetector(
onHorizontalDragUpdate: (v){
onHorizontalDragUpdate(v);
},
onHorizontalDragEnd: (v) {
onHorizontalDragEnd(v);
},
child: Transform.translate(
offset: Offset(translateX, 0),
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: widget.child,
)
],
),
),
),
],
);
throw UnimplementedError();
}
void onHorizontalDragUpdate(DragUpdateDetails details) {
translateX = (translateX + details.delta.dx).clamp(-widget.actionsWidth, 0.0);
setState(() {
});
}
void onHorizontalDragEnd(DragEndDetails details) {
animationController.value = translateX;
if (details.velocity.pixelsPerSecond.dx > 200) {
close();
} else if (details.velocity.pixelsPerSecond.dx < -200) {
open();
} else {
if (translateX.abs() > widget.actionsWidth / 2) {
open();
} else {
close();
}
}
}
void open() {
if (translateX != -widget.actionsWidth) {
animationController.animateTo(-widget.actionsWidth);
}
}
void close() {
if (translateX != 0) {
animationController.animateTo(0);
}
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
}
//左滑出现“删除”效果
class SlideDelete extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _SlideDelete();
throw UnimplementedError();
}
}
class _SlideDelete extends State<SlideDelete> {
//确定删除嘛
bool delete =false;
@override
Widget build(BuildContext context) {
return Center(
child: Container(
alignment: Alignment.center,
height: 70,
child: Slide(
GestureDetector(
onTap: (){},
child: _createItem(),
),
100,
<Widget>[
_createDelete(),
]),
),
);
throw UnimplementedError();
}
//左滑删除
_createDelete() {
return GestureDetector(
onTap: () {
if (delete) {
print("点击删除");
} else {
setState(() {
delete = !delete;
});
}
},
child: Container(
alignment: Alignment.center,
width: 100,
color: Colors.green,
child: Text(delete ?'确定删除' : '删除',style: TextStyle(fontSize: 30),),
),
);
}
//item
Widget _createItem() {
return Container(
child: Container(
color: Colors.white,
margin: EdgeInsets.only(left: 4),
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('左滑删除',style: TextStyle(fontSize: 30),),
SizedBox(height: 5,),
],
),
),
),
);
}
}