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

 更新时间:2021年05月21日 15:40:50   作者:Mannaoz  
最近接了一个新项目,需要开发带有删除动画效果的listview功能,在实现过程中列表滚动效果用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删除内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android原生绘图工具Paint详细

    Android原生绘图工具Paint详细

    这篇文章要给大家分享的是Android原生绘图工具Paint,android中提供了类似的工具Canvas和Paint,分别对应画布和画笔,本文就来介绍Androi中的Paint,感兴趣的小伙伴一起来学习下面文章内容
    2021-09-09
  • RecyclerView实现流式标签单选多选功能

    RecyclerView实现流式标签单选多选功能

    RecyclerView是Android一个更强大的控件,其不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足。这篇文章主要介绍了RecyclerView实现的流式标签单选多选功能,需要的朋友可以参考下
    2019-11-11
  • 安卓模拟器genymotion的安装与使用图文教程

    安卓模拟器genymotion的安装与使用图文教程

    这篇文章主要为大家详细介绍了安卓模拟器genymotion的安装与使用图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Android Studio中主题样式的使用方法详解

    Android Studio中主题样式的使用方法详解

    这篇文章主要介绍了Android Studio中主题样式的使用方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • Android使用ViewDragHelper实现图片下拽返回示例

    Android使用ViewDragHelper实现图片下拽返回示例

    这篇文章主要介绍了Android使用ViewDragHelper实现图片下拽返回示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • Android自定义弹出框dialog效果

    Android自定义弹出框dialog效果

    这篇文章主要为大家详细介绍了Android自定义弹出框dialog效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • android轻松管理安卓应用中的log日志 发布应用时log日志全部去掉的方法

    android轻松管理安卓应用中的log日志 发布应用时log日志全部去掉的方法

    android合理的管理log日志,在开发的时候打印出来,在发布的时候,把所有的log日志全部关掉,下面就把方法给你一一道来
    2013-11-11
  • Android10.0实现本地音乐播放(附源码下载)

    Android10.0实现本地音乐播放(附源码下载)

    这篇文章主要介绍了Android10.0实现本地音乐播放(附源码下载),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • android notification 的总结分析

    android notification 的总结分析

    notification是一种出现在任务栏的提示,特别是在4.0以后notification改进了不少,本文内容都是基于4.0及4.1以后总结来的
    2013-05-05
  • OpenHarmony如何调用电话服务API拨打电话

    OpenHarmony如何调用电话服务API拨打电话

    OpenHarmony3.1版本标准系统增加了通话相关的联系人应用,来电应用等,在系统服务层面电话相关功能也比较完善,这篇文章主要介绍了OpenHarmony如何调用电话服务API拨打电话
    2022-11-11

最新评论