前言
在Flutter开发中,基于原生移动端开发的思想也会运用到混合开发中,尤其是原生移动的的好的特性和交互效果更是如此。在现在的发展情况下,Flutter下的混合开发已经越来越替代原生移动的开发,同时也会继承原生开发的优点,那么本文就来分享一下关于Flutter开发中仿iOS原生向左侧滑删除cell的item的效果,记录下来,方便查阅使用。
侧滑删除功能
首先来了解一下侧滑删除功能,移动端实际开发过程中关于侧滑删除的使用是非场景的操作,早期原生app开发的时候侧滑删除功能只有iOS的侧滑删除做的最“丝滑”,直到后来混合开发的兴起以及原生开发的进一步发展,侧滑删除的效果逐渐在各端保持了越来越一致的效果。在app中,最常用的侧滑删除是运用在列表展示,比如侧滑删除列表某一行数据,再比如最常见的聊天记录列表侧滑删除某一条记录等等,这些都是最常用的侧滑删除的使用场景。
Flutter的侧滑删除
在Flutter中,侧滑删除的使用和原生app中的侧滑删除类似,只是使用的控件不一样罢了。Flutter中要想实现侧滑删除,就需要使用控件Dismissble,它是直接实现侧滑删除的功能。Flutter的源码是这样介绍Dismissble的:
A widget that can be dismissed by dragging in the indicated [direction].
上面的源码介绍也就一句话,大概意思就是可以通过在指定的方向上拖动来关闭的小部件。具体的使用下面会介绍到。
侧滑删除实现
实现侧滑删除的功能效果,其实可以分为两个模块:一、实现侧滑出现删除的模块,也就是通过水平滑动平移的控件;二、实现删除按钮的模块,默认时候不显示,只有在滑动侧滑平移之后才显示出来。
那么接下来就来分享一下关于实现Flutter的侧滑删除的功能,这里以常用的向左侧滑删除为例,主要就是Dismissble控件的使用和侧滑显示删除按钮以及通过手势监听水平滑动等功能的实现,具体核心源代码如下所示:
// @dart=2.9
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const Scaffold(
body: SlideDelete(),
),
);
}
}
class Slide extends StatefulWidget {
List<Widget> actions;
Widget child;
double actionsWidth;
Slide(
this.child,
this.actionsWidth,
this.actions,
{Key key}
) : super(key: key);
@override
State<StatefulWidget> createState() {
return _Slide();
}
}
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: const 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,
)
],
),
),
),
],
);
}
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 {
const SlideDelete({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _SlideDelete();
}
}
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(),
]),
),
);
}
//左滑删除
_createDelete() {
return GestureDetector(
onTap: () {
if (delete) {
print("点击删除");
} else {
setState(() {
delete = !delete;
});
}
},
child: Container(
alignment: Alignment.center,
width: 100,
color: Colors.red,
child: Text(delete ?'确定删除' : '删除',style: const TextStyle(fontSize: 14, color: Colors.white, decoration: TextDecoration.none),),
),
);
}
//item
Widget _createItem() {
return Container(
color: Colors.white,
margin: const EdgeInsets.only(left: 4.0),
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text('左滑删除',style: TextStyle(fontSize: 16.0, decoration: TextDecoration.none),),
SizedBox(height: 5.0,),
],
),
),
);
}
}
通过上面的源码可以实现简单的具体的Flutter向左侧滑删除的功能,运行效果如下所示:
最后
通过本文关于Flutter开发中仿iOS侧滑删除效果的实现的介绍,想必在以后的Flutter开发中遇到类似的业务需求就会游刃有余,因为在Flutter开发中侧滑删除也是非常常见且重要的使用点。如果认真阅读并且实践示例,尤其是从事Flutter开发不久的开发者来说尤为重要,是一篇值得阅读的文章,且在实际开发中也是必用知识点,所以说这个知识点是必备的,重要性就不在赘述。欢迎关注,一起交流,共同进步。