温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

flutter如何实现带删除动画的listview功能

发布时间:2021-05-22 09:41:11 来源:亿速云 阅读:368 作者:小新 栏目:开发技术

这篇文章将为大家详细讲解有关flutter如何实现带删除动画的listview功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

个人开发app中,需要开发一个带有删除功能的ListView

效果如下

flutter如何实现带删除动画的listview功能

需求动画分析

列表可以滚动用listView,

有两个动画,第一个动画是透明度变化,第二个是size变化

是顺序执行

实现过程

新建一个动画页面进行单独控制

记得用statefulwidget类,这第二个动画之间涉及到页面刷新切换widget

记得with tickerproviderstatemixin 这个是动画类状态管理的必备

class AnimationListItem extends StatefulWidget {   AnimationListItem();   @override   _AnimationListItemState createState() => _AnimationListItemState(); } class _AnimationListItemState extends State<AnimationListItem>     with TickerProviderStateMixin {   @override   Widget build(BuildContext context) {     // TODO: implement build     return Container();   } }

动画流程

声明

//控制器   AnimationController lucencyController;   AnimationController sizeController; // 动画   Animation<double> lucencyAnimation;   Animation<double> sizeAnimation;

初始化

///必须在initstate这个生命周期进行初始化   @override   void initState() {     // TODO: implement initState     super.initState();     lucencyController =         AnimationController(vsync: this, duration: Duration(milliseconds: 150));     lucencyAnimation = Tween(begin: 1.0, end: 0.0).animate(         CurvedAnimation(parent: lucencyController, curve: Curves.easeOut));     sizeController =         AnimationController(vsync: this, duration: Duration(milliseconds: 250));     sizeAnimation = Tween(begin: 1.0, end: 0.0).animate(         CurvedAnimation(parent: sizeController, curve: Curves.easeOut));   }

注销

@override   void dispose() {     lucencyController.dispose();     sizeController.dispose();     super.dispose();   }

最后内容呈现

class AnimationListItem extends StatefulWidget {   AnimationListItem();   @override   _AnimationListItemState createState() => _AnimationListItemState(); } class _AnimationListItemState extends State<AnimationListItem>     with TickerProviderStateMixin {   AnimationController lucencyController;   AnimationController sizeController;   Animation<double> lucencyAnimation;   Animation<double> sizeAnimation;   bool isChange = false;   @override   void initState() {     // TODO: implement initState     super.initState();     lucencyController =         AnimationController(vsync: this, duration: Duration(milliseconds: 150));     lucencyAnimation = Tween(begin: 1.0, end: 0.0).animate(         CurvedAnimation(parent: lucencyController, curve: Curves.easeOut));     sizeController =         AnimationController(vsync: this, duration: Duration(milliseconds: 250));     sizeAnimation = Tween(begin: 1.0, end: 0.0).animate(         CurvedAnimation(parent: sizeController, curve: Curves.easeOut));   }   @override   Widget build(BuildContext context) {     return buildItemBox();   }   @override   void dispose() {     lucencyController.dispose();     sizeController.dispose();     super.dispose();   }   Widget buildItemBox() {     return isChange         ? SizeTransition(             axis: Axis.vertical,             sizeFactor: sizeAnimation,             child: Container(               height: duSetWidth(100),               width: double.infinity,             ),           )         : FadeTransition(             opacity: lucencyAnimation,             child: Container(               alignment: Alignment.center,               padding: EdgeInsets.only(                 left: duSetWidth(15),                 right: duSetWidth(15),               ),               height: duSetWidth(100),               child: buildRow(),             ),           );   }   Widget buildRow() {     ///设置显示的样式     bool _isSub = false;     Color _isSubColor = Color.fromRGBO(245, 77, 130, 1);     Color _isSubBackColor = Colors.transparent;     Widget isSubWidget = InkWell(       child: Container(         alignment: Alignment.center,         width: duSetWidth(55),         height: duSetWidth(28),         decoration: BoxDecoration(           color: _isSubBackColor,           border: Border.all(color: _isSubColor),           borderRadius: BorderRadius.circular(duSetWidth(15)),         ),         child: Text(           '+ 书架',           style: TextStyle(             color: _isSubColor,           ),         ),       ),       onTap: () {         if (_isSub)           print('dasd');         else           print('dsada');       },     );     return Row(       mainAxisAlignment: MainAxisAlignment.spaceBetween,       children: [         Container(           width: duSetWidth(60),           height: duSetWidth(80),           child: ClipRRect(             borderRadius: BorderRadius.circular(duSetWidth(5)),             child: Image.network(               'https://gimg2.baidu.com/image_search/src=http%3A%2F%2F00.minipic.eastday.com%2F20170307%2F20170307164725_114ea3c04f605e59bd10699f37870267_13.jpeg&refer=http%3A%2F%2F00.minipic.eastday.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1623596389&t=946dba98698d8d67d773ea8f7af55f45',               fit: BoxFit.cover,             ),           ),         ),         Container(           width: duSetWidth(155),           height: duSetWidth(80),           child: Column(             mainAxisAlignment: MainAxisAlignment.center,             children: [               Container(                 height: duSetWidth(25),                 alignment: Alignment.centerLeft,                 width: double.infinity,                 child: Text(                   '这是标题',                   maxLines: 1,                   overflow: TextOverflow.ellipsis,                   style: TextStyle(                     color: Colors.white,                     fontSize: duSetFontSize(16),                   ),                 ),               ),               Container(                 height: duSetWidth(20),                 alignment: Alignment.centerLeft,                 width: double.infinity,                 child: Text(                   '这是副标题',                   maxLines: 1,                   overflow: TextOverflow.ellipsis,                   style: TextStyle(                     color: Color.fromRGBO(162, 168, 186, 1),                     fontSize: duSetFontSize(14),                   ),                 ),               ),             ],           ),         ),         Container(           width: duSetWidth(100),           height: duSetWidth(80),           padding: EdgeInsets.only(             top: duSetWidth(4),           ),           alignment: Alignment.center,           child: Row(             mainAxisAlignment: MainAxisAlignment.spaceBetween,             children: [               isSubWidget,               InkWell(                 onTap: () async {                   await lucencyController.forward();                   setState(() {                     isChange = true;                     sizeController.forward();                   });                 },                 child: Container(                   alignment: Alignment.center,                   width: duSetWidth(35),                   height: duSetWidth(28),                   decoration: BoxDecoration(                     border: Border.all(                       color: Color.fromRGBO(113, 118, 140, 1),                     ),                     borderRadius: BorderRadius.circular(duSetWidth(15)),                   ),                   child: Icon(                     Icons.delete,                     color: Color.fromRGBO(113, 118, 140, 1),                     size: duSetFontSize(16),                   ),                 ),               ),             ],           ),         )       ],     );   } }

dusetwidth是我自定义的函数可以不用管,自己替换

下列是在页面使用

class HistoryPage extends StatefulWidget {   @override   _HistoryPageState createState() => _HistoryPageState(); } class _HistoryPageState extends State<HistoryPage> {    @override   Widget build(BuildContext context) {     return Scaffold(       appBar: AppBar(),       body: ListView(         children: [           AnimationListItem(),           AnimationListItem(),           AnimationListItem(),           AnimationListItem(),         ],       ),     );   }   /// 构造appbar   Widget buildAppabr() {     return AppBar(       backgroundColor: Color.fromRGBO(33, 39, 46, 1),       brightness: Brightness.dark,       centerTitle: true,       title: Text(         '浏览记录',         style: TextStyle(           fontSize: duSetFontSize(16),           color: Colors.white,         ),       ),       leading: IconButton(         icon: Icon(           Icons.arrow_back_ios,           color: Colors.white,           size: duSetFontSize(18),         ),         onPressed: () {           Get.back();         },       ),     );   } }

这个我原来是准备使用animatedList来进行实现的,最后发现,animatedList里面只能设置移除动画,不能实现补位动画

第一个透明度的动画就是移除动画,第二个size变化就是补位动画,

animatedList没有补位,所以下方list直接移动上去会显得非常突兀,我看了看源码,修改较为麻烦。所以就直接用动画变换来写

这个List内的内容,并不是直接移除,而是替换成高低为0 的一个盒子

关于“flutter如何实现带删除动画的listview功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI