经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
flutter 实现 有删除动画的 listview
来源:cnblogs  作者:Mannaoz  时间:2021/5/17 9:06:44  对本文有异议

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

效果如下

 

 

需求动画分析

 

列表可以滚动用listView,

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

是顺序执行

 

实现过程

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

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

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

  1. class AnimationListItem extends StatefulWidget {
  2. AnimationListItem();
  3. @override
  4. _AnimationListItemState createState() => _AnimationListItemState();
  5. }
  6. class _AnimationListItemState extends State<AnimationListItem>
  7. with TickerProviderStateMixin {
  8. @override
  9. Widget build(BuildContext context) {
  10. // TODO: implement build
  11. return Container();
  12. }
  13. }

 

动画流程

声明

  1. //控制器
  2. AnimationController lucencyController;
  3. AnimationController sizeController;
  4. // 动画
  5. Animation<double> lucencyAnimation;
  6. Animation<double> sizeAnimation;

 

初始化

  1. ///必须在initstate这个生命周期进行初始化
  2. @override
  3. void initState() {
  4. // TODO: implement initState
  5. super.initState();
  6. lucencyController =
  7. AnimationController(vsync: this, duration: Duration(milliseconds: 150));
  8. lucencyAnimation = Tween(begin: 1.0, end: 0.0).animate(
  9. CurvedAnimation(parent: lucencyController, curve: Curves.easeOut));
  10. sizeController =
  11. AnimationController(vsync: this, duration: Duration(milliseconds: 250));
  12. sizeAnimation = Tween(begin: 1.0, end: 0.0).animate(
  13. CurvedAnimation(parent: sizeController, curve: Curves.easeOut));
  14. }

 

注销 

  1. @override
  2. void dispose() {
  3. lucencyController.dispose();
  4. sizeController.dispose();
  5. super.dispose();
  6. }

 

最后内容呈现

  1. class AnimationListItem extends StatefulWidget {
  2. AnimationListItem();
  3. @override
  4. _AnimationListItemState createState() => _AnimationListItemState();
  5. }
  6. class _AnimationListItemState extends State<AnimationListItem>
  7. with TickerProviderStateMixin {
  8. AnimationController lucencyController;
  9. AnimationController sizeController;
  10. Animation<double> lucencyAnimation;
  11. Animation<double> sizeAnimation;
  12. bool isChange = false;
  13. @override
  14. void initState() {
  15. // TODO: implement initState
  16. super.initState();
  17. lucencyController =
  18. AnimationController(vsync: this, duration: Duration(milliseconds: 150));
  19. lucencyAnimation = Tween(begin: 1.0, end: 0.0).animate(
  20. CurvedAnimation(parent: lucencyController, curve: Curves.easeOut));
  21. sizeController =
  22. AnimationController(vsync: this, duration: Duration(milliseconds: 250));
  23. sizeAnimation = Tween(begin: 1.0, end: 0.0).animate(
  24. CurvedAnimation(parent: sizeController, curve: Curves.easeOut));
  25. }
  26. @override
  27. Widget build(BuildContext context) {
  28. return buildItemBox();
  29. }
  30. @override
  31. void dispose() {
  32. lucencyController.dispose();
  33. sizeController.dispose();
  34. super.dispose();
  35. }
  36. Widget buildItemBox() {
  37. return isChange
  38. ? SizeTransition(
  39. axis: Axis.vertical,
  40. sizeFactor: sizeAnimation,
  41. child: Container(
  42. height: duSetWidth(100),
  43. width: double.infinity,
  44. ),
  45. )
  46. : FadeTransition(
  47. opacity: lucencyAnimation,
  48. child: Container(
  49. alignment: Alignment.center,
  50. padding: EdgeInsets.only(
  51. left: duSetWidth(15),
  52. right: duSetWidth(15),
  53. ),
  54. height: duSetWidth(100),
  55. child: buildRow(),
  56. ),
  57. );
  58. }
  59. Widget buildRow() {
  60. ///设置显示的样式
  61. bool _isSub = false;
  62. Color _isSubColor = Color.fromRGBO(245, 77, 130, 1);
  63. Color _isSubBackColor = Colors.transparent;
  64. Widget isSubWidget = InkWell(
  65. child: Container(
  66. alignment: Alignment.center,
  67. width: duSetWidth(55),
  68. height: duSetWidth(28),
  69. decoration: BoxDecoration(
  70. color: _isSubBackColor,
  71. border: Border.all(color: _isSubColor),
  72. borderRadius: BorderRadius.circular(duSetWidth(15)),
  73. ),
  74. child: Text(
  75. '+ 书架',
  76. style: TextStyle(
  77. color: _isSubColor,
  78. ),
  79. ),
  80. ),
  81. onTap: () {
  82. if (_isSub)
  83. print('dasd');
  84. else
  85. print('dsada');
  86. },
  87. );
  88. return Row(
  89. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  90. children: [
  91. Container(
  92. width: duSetWidth(60),
  93. height: duSetWidth(80),
  94. child: ClipRRect(
  95. borderRadius: BorderRadius.circular(duSetWidth(5)),
  96. child: Image.network(
  97. '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',
  98. fit: BoxFit.cover,
  99. ),
  100. ),
  101. ),
  102. Container(
  103. width: duSetWidth(155),
  104. height: duSetWidth(80),
  105. child: Column(
  106. mainAxisAlignment: MainAxisAlignment.center,
  107. children: [
  108. Container(
  109. height: duSetWidth(25),
  110. alignment: Alignment.centerLeft,
  111. width: double.infinity,
  112. child: Text(
  113. '这是标题',
  114. maxLines: 1,
  115. overflow: TextOverflow.ellipsis,
  116. style: TextStyle(
  117. color: Colors.white,
  118. fontSize: duSetFontSize(16),
  119. ),
  120. ),
  121. ),
  122. Container(
  123. height: duSetWidth(20),
  124. alignment: Alignment.centerLeft,
  125. width: double.infinity,
  126. child: Text(
  127. '这是副标题',
  128. maxLines: 1,
  129. overflow: TextOverflow.ellipsis,
  130. style: TextStyle(
  131. color: Color.fromRGBO(162, 168, 186, 1),
  132. fontSize: duSetFontSize(14),
  133. ),
  134. ),
  135. ),
  136. ],
  137. ),
  138. ),
  139. Container(
  140. width: duSetWidth(100),
  141. height: duSetWidth(80),
  142. padding: EdgeInsets.only(
  143. top: duSetWidth(4),
  144. ),
  145. alignment: Alignment.center,
  146. child: Row(
  147. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  148. children: [
  149. isSubWidget,
  150. InkWell(
  151. onTap: () async {
  152. await lucencyController.forward();
  153. setState(() {
  154. isChange = true;
  155. sizeController.forward();
  156. });
  157. },
  158. child: Container(
  159. alignment: Alignment.center,
  160. width: duSetWidth(35),
  161. height: duSetWidth(28),
  162. decoration: BoxDecoration(
  163. border: Border.all(
  164. color: Color.fromRGBO(113, 118, 140, 1),
  165. ),
  166. borderRadius: BorderRadius.circular(duSetWidth(15)),
  167. ),
  168. child: Icon(
  169. Icons.delete,
  170. color: Color.fromRGBO(113, 118, 140, 1),
  171. size: duSetFontSize(16),
  172. ),
  173. ),
  174. ),
  175. ],
  176. ),
  177. )
  178. ],
  179. );
  180. }
  181. }

 

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

 

下列是在页面使用

  1. class HistoryPage extends StatefulWidget {
  2. @override
  3. _HistoryPageState createState() => _HistoryPageState();
  4. }
  5. class _HistoryPageState extends State<HistoryPage> {
  6.  @override
  7. Widget build(BuildContext context) {
  8. return Scaffold(
  9. appBar: AppBar(),
  10. body: ListView(
  11. children: [
  12. AnimationListItem(),
  13. AnimationListItem(),
  14. AnimationListItem(),
  15. AnimationListItem(),
  16. ],
  17. ),
  18. );
  19. }
  20. /// 构造appbar
  21. Widget buildAppabr() {
  22. return AppBar(
  23. backgroundColor: Color.fromRGBO(33, 39, 46, 1),
  24. brightness: Brightness.dark,
  25. centerTitle: true,
  26. title: Text(
  27. '浏览记录',
  28. style: TextStyle(
  29. fontSize: duSetFontSize(16),
  30. color: Colors.white,
  31. ),
  32. ),
  33. leading: IconButton(
  34. icon: Icon(
  35. Icons.arrow_back_ios,
  36. color: Colors.white,
  37. size: duSetFontSize(18),
  38. ),
  39. onPressed: () {
  40. Get.back();
  41. },
  42. ),
  43. );
  44. }
  45. }

 

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

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

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

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

如果有animatedList简单的改造实现的补位动画,希望留言给我地址,非常感谢

原文链接:http://www.cnblogs.com/mannaoz/p/14770526.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号