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

个人开发app中,需要开发一个带有删除功能的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 的一个盒子

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

到此这篇关于flutter实现带删除动画的listview功能的文章就介绍到这了,更多相关flutter listview删除内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Flutter ListView 上拉加载更多下拉刷新功能实现方法

    先上图 下拉刷新 跟原生开发一样,下拉刷新在flutter里提供的有组件实现 RefreshIndicator 一直不明白为啥组件中都提供下拉刷新,但就是没有上拉加载!! 我这请求接口数据用的是 http 库,是个第三方的是需要安装的 https://pub.dev/packages/http 用法如下 class MyHomePage extends StatefulWidget { MyHomePage({Key key}) : super(key: key); @override MyHo

  • flutter RotationTransition实现旋转动画

    本文实例为大家分享了flutter RotationTransition实现旋转动画的具体代码,供大家参考,具体内容如下 flutter 动画状态监听器 AnimationController //动画控制器 AnimationController controller; //AnimationController是一个特殊的Animation对象,在屏幕刷新的每一帧,就会生成一个新的值, // 默认情况下,AnimationController在给定的时间段内会线性的生成从0.0到1.0的数字

  • Flutter路由的跳转、动画和传参详解(最简单)

    路由 做Android/iOS原生开发的时候,要打开一个新的页面,你得知道你的目标页面对象,然后初始化一个Intent或者ViewController,再通过startActivity或者pushViewController来推出一个新的页面,不能跟web一样,直接丢一个链接地址就跳转到新的页面.当然,可以自己去加一个中间层来实现这些功能. Flutter里面是原生支持路由的.Flutter的framework提供了路由跳转的实现.我们可以直接使用这些功能. Flutter路由介绍 Flutte

  • android使用flutter的ListView实现滚动列表的示例代码

    现如今打开一个 App,比如头条.微博,都会有长列表,随着我们不断地滑动,视窗内的内容也会不断地更新.今天就用 Flutter 实现一下这种效果. 这里的表现其实就相当于有一个固定长度的容器,然后超出的内容是不可见的,只有当你向上或向下滑动屏幕时,视窗外看不见的内容才会出现在视窗中.如果在 web 开发时,是需要容器加上样式 overflow: auto; 要想用 Flutter 实现,其实也是很简单的,因为 Flutter 为我们提供了 ListView 组件. ListView 主要有以下几

  • Flutter中ListView 的使用示例

    这个小例子使用的是豆瓣 API 中 正在上映的电影 的开放接口,要实现的主要效果如下: JSON 数据结构 Item 结构 Item 的结构是一个 Card 包含着一个 Row 然后这个 Row 里面左边是一个 Image ,右边是一个 Column 功能实现 material 库 Json 解析 网络请求 加载菊花 要实现上面四个功能,我们首先需要在 .dart 文件中引入如下代码 import 'dart:convert'; import 'package:http/http.dart' a

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

    个人开发app中,需要开发一个带有删除功能的ListView 效果如下 需求动画分析 列表可以滚动用listView, 有两个动画,第一个动画是透明度变化,第二个是size变化 是顺序执行 实现过程 新建一个动画页面进行单独控制 记得用statefulwidget类,这第二个动画之间涉及到页面刷新切换widget 记得with tickerproviderstatemixin 这个是动画类状态管理的必备 class AnimationListItem extends StatefulWidget

  • 仿IOS效果 带弹簧动画的ListView

    最近项目打算做一个界面,类似于dayone首页的界面效果,dayone 是一款付费应用,目前只有IOS端.作为一个资深懒惰的程序员,奉行的宗旨是绝对不重复造一个轮子.于是乎,去网上找一大堆开源项目,发现没有找到合适的,然后,只能硬着头皮自己来了.先看看效果: 效果图 其实写起来也比较简单,就是控制ListView的头部和底部的高度就可以了, 如果用RecycleView实现起来也是一样,只是RecycleView添加头和尾巴稍微麻烦一点,处理点击事件也不是很方便,所以就基于ListView去实现

  • Android实现自定义带删除功能的EditText实例

    1.说明 自定义带删除功能的EditText有两种方法,第一种是用组合视图的方法,即在一个view视图里面左侧放置一个EditText,右侧放置一个ImageView,但是这样增加了视图的层次,而且对输入内容的长度要做一定的处理. 第二种是重新定义EditText组件,增加相应的事件处理,即可达到很好的效果,效果图如下: 2.ClearEditText的JAVA类文件 /** * @说明: 自定义带删除按钮的EditText * */ public class ClearEditText ext

  • Android 模仿QQ侧滑删除ListView功能示例

    需求: 1.listView可以侧滑item,展示删除按钮,点击删除按钮,删除当前的item 2.在删除按钮展示时,点击隐藏删除按钮,不响应item的点击事件 3.在删除按钮隐藏时,点击item响应点击事件 根据以上需求在网络上查找响应的例子,也有仿QQ侧滑代码,但不能满足2和3的要求,因此修改了一把,代码如下,共大家拍砖 第一步:重写ListView public class SwipeListView extends ListView { private final static Strin

  • Android中RecyclerView实现滑动删除与拖拽功能

    前言 从Android 5.0开始,谷歌推出了新的控件RecyclerView,相对于早它之前的ListView,优点多多,功能强大,也给我们的开发着提供了极大的便利,今天自己学习一下RecyclerView轻松实现滑动删除及拖拽的效果. 如下图. 相信研究过RecyclerView的同学,应该很清楚该怎么实现这样的效果,若是用ListView,这样的效果实现起来可能就有点麻烦,但是在强大的RecyclerView面前这样的的效果只需很少的代码,因为谷歌给我们提供了强大的工具类ItemTouch

  • Flutter实现不同缩放动画效果详解

    目录 需求背景 可缩放组件介绍 ScaleTransition SizeTransition AnimatedSize AnimatedBuilder 小结 需求背景 组件缩放可以向着一个方向进行缩放,放大列表中某一个Cell期望它是向后进行放大而非组件中心点开始缩放.具体效果如下图所示: 可缩放组件介绍 ScaleTransition ScaleTransition具体实现如下代码,设置AnimationController控制器若需要增加数值操作可以再增加Animate再调用forward方

  • Android 实现带字母索引的侧边栏功能

    之前已经用自定义View做出如下这样一个效果了 这两天需要重新拿来使用,发现效果虽然做出来了,不过思路不太对,就重新参考写了一个,用法也更为简单了 首要的自然是需要继承View绘制出侧边栏,并向外提供一个监听字母索引变化的方法 /** * 作者:叶应是叶 * 时间:2017/8/20 11:38 * 描述: */ public class LetterIndexView extends View { public interface OnTouchingLetterChangedListener

  • Android自定义带增长动画和点击弹窗提示效果的柱状图DEMO

    项目中最近用到各种图表,本来打算用第三方的,例如MPAndroid,这是一个十分强大的图表库,应用起来十分方便,但是最终发现和设计不太一样,没办法,只能自己写了.今天将写好的柱状图的demo贴在这,该柱状图可根据数据的功能有一下几点: 1. 根据数据的多少,动态的绘制柱状图柱子的条数: 2. 柱状图每条柱子的绘制都有动态的动画效果: 3. 每条柱子有点击事件,点击时弹出提示框,显示相关信息,规定时间后,弹窗自动消失. 好了,先上演示图: 下边贴出相关代码: 自定义柱状图类: package co

  • Android仿QQ长按删除弹出框功能示例

    废话不说,先看一下效果图,如果大家感觉不错,请参考实现代码: 对于列表来说,如果想操作某个列表项,一般会采用长按弹出菜单的形式,默认的上下文菜单比较难看,而QQ的上下文菜单就人性化多了,整个菜单给用户一种气泡弹出的感觉,而且会显示在手指按下的位置,而技术实现我之前是使用popupWindow和RecyclerView实现的,上面一个RecyclerView,下面一个小箭头ImageView,但后来发现没有必要,而且可定制化也不高,还是使用多个TextView更好一点. 我封装了一下,只需要一个P

  • Android开发实现可拖动排序的ListView功能【附源码下载】

    本文实例讲述了Android开发实现可拖动排序的ListView功能.分享给大家供大家参考,具体如下: 一.上图 二.简述 1.需要实现的效果是长按右侧可拖动部分布局实现列表项的拖动排序 2.当点击列表项前面的单选按钮时,在该条目右侧显示删除图标,点击该图标删除当前条目. 三.实现思路 借助github上的开源代码drag-sort-listview-master加以改造. 四.主要源码展示 1.Activity代码 package com.gengducun.dslvdemo; import

随机推荐