Flutter-自定义表情雨下落动画

简述

今天给大家分享一个Flutter的表情雨的实现,具体的效果见下图,这个效果其实是工作中的一个小小的需求,这里面单独拿出来讲讲下这个效果的实现思路。

在以前特别是新手,遇到一些动画效果都是拿到需求后,在网络上去找寻类似的效果,然后修改修改就可以了,不知道你们是不是呢?其实从chatgpt出来以后,很多时候对于这种效果我们其实直接就可以问下gpt,gpt会给我们一些思路,只要我们表达的清晰,配合gpt我们会很快实现这个效果。

效果图

emoji.gif

分析

我们如何去问gpt,才能让gpt给出我们想要的结果呢?当然在以前我们都是自己先了解这个效果属于什么效果,比如说 “跑马灯”、“画廊”等等,然后在网络搜索这个关键字查询。但是现在我们不是单纯的搜关键字了,而是用自己的语言把效果用话语表达出来,让gpt知道到底怎么写代码,总结来说你就是产品,gpt是开发人员,你要把产品需求告诉gpt去开发。

ChatGpt问答

用户问:请使用Flutter实现一个widget,这个widget支持设置宽高,其内容是由n个表情从上往下落下,这些表情下落的时机是间隔落下,下落过程中透明度在高度一半的时候透明度逐渐隐藏。
注意: 这里我使用的gpt是3.5版本。

gpt回答代码如下:

import 'dart:async';
import 'dart:math';import 'package:flutter/material.dart';class FallingEmojisWidget extends StatefulWidget {final double width;final double height;final List<String> emojis;final Duration interval;const FallingEmojisWidget({Key? key,required this.width,required this.height,required this.emojis,this.interval = const Duration(milliseconds: 500),}) : super(key: key);@override_FallingEmojisWidgetState createState() => _FallingEmojisWidgetState();
}class _FallingEmojisWidgetState extends State<FallingEmojisWidget>with TickerProviderStateMixin {late AnimationController _animationController;late Timer _timer;List<Widget> _emojiWidgets = [];@overridevoid initState() {super.initState();_animationController = AnimationController(vsync: this,duration: Duration(milliseconds: 1000),);_timer = Timer.periodic(widget.interval, (_) => _addEmoji());}@overridevoid dispose() {_animationController.dispose();_timer.cancel();super.dispose();}void _addEmoji() {setState(() {final emoji = widget.emojis[Random().nextInt(widget.emojis.length)];_emojiWidgets.add(_buildEmojiWidget(emoji));});}Widget _buildEmojiWidget(String emoji) {final initialOffset = Offset(Random().nextDouble() * widget.width,-50,);final targetOffset = Offset(initialOffset.dx,widget.height / 2,);final animation = Tween<Offset>(begin: initialOffset,end: targetOffset,).animate(CurvedAnimation(parent: _animationController,curve: Curves.easeInOut,));return AnimatedBuilder(animation: _animationController,builder: (context, child) {final opacity = _animationController.value < 0.5? (_animationController.value * 2): (1 - (_animationController.value - 0.5) * 2);return Positioned(left: animation.value.dx,top: animation.value.dy,child: Opacity(opacity: opacity,child: Text(emoji,style: TextStyle(fontSize: 24),),),);},);}@overrideWidget build(BuildContext context) {return Container(width: widget.width,height: widget.height,child: Stack(children: _emojiWidgets,),);}
}`

gpt第一次回答你的代码其实已经告诉你实现思路了,比如上面的代码,通过gpt的回答我们知道可以使用Stack控件,然后在Stack中添加我们想要的数量的表情widget,然后通过AnimatedBuilder+Positioned实现表情下落的效果。是不是很6,从开始没有思路立马就知道如何实现了,你其实可以直接copy gpt的回答然后运行看看,在此基础上修改修改就ok了。下面是我修改后的完整代码。

import 'dart:math';
import 'package:flutter/material.dart';/// 表情下落动画
class EmojiAnimWidget extends StatefulWidget {const EmojiAnimWidget({Key? key,required this.width,required this.height,this.emojiNum = 6,this.duration = const Duration(seconds: 5)}): super(key: key);final double width;final double height;final int emojiNum;final Duration duration;@overrideState<EmojiAnimWidget> createState() => EmojiAnimWidgetState();
}class EmojiAnimWidgetState extends State<EmojiAnimWidget>with SingleTickerProviderStateMixin {late AnimationController _animationController;List<Widget>? _emojis;@overridevoid initState() {super.initState();_animationController = AnimationController(vsync: this,duration: widget.duration,);}@overridevoid dispose() {_animationController.dispose();super.dispose();}/// 开始表情动画void startEmojiAnim(String emoji) {_emojis = List.generate(widget.emojiNum, (index) {var delay = Random().nextInt(150).toDouble() + 50;var fontSize = Random().nextInt(9).toDouble() + 18.0;var animation = Tween<double>(begin: 0.0,end: 1.0,).animate(CurvedAnimation(parent: _animationController,curve: Interval(delay / 500, (delay + 300) / 500, curve: Curves.linear),));return AnimatedBuilder(animation: _animationController,builder: (context, child) {var opacity = 1 - animation.value;return Positioned(left: (widget.width - 32) / widget.emojiNum * index,top: -delay + animation.value * (widget.height + delay),child: Opacity(opacity: (opacity > 0.5) ? 1 : opacity,child: Container(height: 50,color: Colors.transparent,alignment: Alignment.center,child: Text(emoji,style: TextStyle(fontSize: fontSize, height: 1.2),textAlign: TextAlign.center,),),),);},);});setState(() {_animationController.stop();_animationController.repeat();_animationController.forward();});}@overrideWidget build(BuildContext context) {if (_emojis == null) return Container();return Container(alignment: Alignment.center,padding: const EdgeInsets.only(left: 16, right: 16),width: widget.width,height: widget.height,child: Stack(clipBehavior: Clip.none,children: _emojis!,),);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/549400.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器人可反向驱动能力与力控架构

反向驱动性是电机传动系统的机械特性&#xff0c;它描述了运动是否可以轻松反转 。特别是&#xff0c;反向驱动能力取决于两个因素&#xff1a;传动运动效率和整体执行器机械阻抗。反向运动中传动装置的低运动效率意味着所施加的外力的大部分被运动反作用力抵消。然而&#xff…

sheng的学习笔记-AI-残差网络-Residual Networks (ResNets)

目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 非常非常深的神经网络&#xff0c;网络发生了退化&#xff08;degradation&#xff09;的现象&#xff1a;随着网络层数的增多&#xff0c;训练集loss逐渐下降&#xff0c;然后趋于饱和&#xff0c;当你再增加网络深度的话&am…

银行OA系统|基于SpringBoot架构+ Mysql+Java+ B/S结构的银行OA系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

Java实现定时发送邮件(基于Springboot工程)

1、功能概述&#xff1f; 1、在企业中有很多需要定时提醒的任务&#xff1a;如每天下午四点钟给第二天的值班人员发送值班消息&#xff1f;如提前一天给参与第二天会议的人员发送参会消息等。 2、这种定时提醒有很多方式如短信提醒、站内提醒等邮件提醒是其中较为方便且廉价的…

uniapp使用uview - DatetimePicker 时间选择器 /时间戳转化

uniapp使用uview - DatetimePicker 时间选择器 /时间戳转化时转换日期格式后页面仍显示时间戳 单元格内显示时间&#xff0c;点击可出现时间选择器切换时间 <u-cell :isLinktrue click"selectTime" title"开始时间" :value"startTime">…

【已解决】在pycharm终端无法激活conda环境,但在cmd命令行中可以

一、问题描述 在windows下winr启动cmd命令行&#xff0c;可以成功运行conda命令并且激活环境在pycharm中打开Terminal终端&#xff0c;发现无法运行conda和pip命令&#xff0c;报错环境无法激活 无法在管道中间运行文档: D:\software\Anaconda3\condabin\conda.bat。 所在位置…

基于Spring Boot的美食分享系统设计与实现

摘 要 美食分享管理&#xff0c;其工作流程繁杂、多样、管理复杂与设备维护繁琐。而计算机已完全能够胜任美食分享管理工作&#xff0c;而且更加准确、方便、快捷、高效、清晰、透明&#xff0c;它完全可以克服以上所述的不足之处。这将给查询信息和管理带来很大的方便&#x…

git常见使用

1. 概念 分布式&#xff0c;有远程仓库和本地仓库的概念&#xff0c;因此要注意同步问题git是面向对象的&#xff0c;本质是内容寻址系统。.git目录下有个文件夹objects&#xff0c;存储git库中的对象&#xff0c;git就是根据object建立一种树形结构&#xff0c;将文件和通过h…

WPS制作甘特图

“ 甘特图&#xff08;Gantt chart&#xff09;又称为横道图、条状图&#xff08;Bar chart&#xff09;&#xff0c;通过条状图来显示项目、进度和其他时间相关的系统进展的内在关系随着时间进展的情况。” 设置基础样式 设置行高 设置宽度 准备基础数据 计算持续时间 …

【早鸟优惠|高录用|EI稳定检索】2024年虚拟现实、图像和信号处理国际学术会议(ICVISP 2024)诚邀投稿/参会!

【早鸟优惠|高录用|EI稳定检索】 2024年虚拟现实、图像和信号处理国际学术会议&#xff08;ICVISP 2024&#xff09;诚邀投稿/参会&#xff01; # 早鸟优惠 # 先投稿先送审 # #投稿免费参会、口头汇报及海报展示# 2024年虚拟现实、图像和信号处理国际学术会议&#xff08;I…

【开发】SpringBoot 整合 Redis

目录 前言 1. Redis 的下载及安装 1.1 Redis 的下载 1.2 安装 Redis 1.3 启动 Redis 2. 创建 SpringBoot 项目整合 Redis 2.1 环境要求 2.2 SpringBoot项目构建 2.2.1 方式一 2.2.2 方式二 2.3 在 pom.xml 文件中导入依赖坐标 2.4 在 application.properties 中加…

STM32CubeIDE基础学习-BEEP蜂鸣器实验

STM32CubeIDE基础学习-BEEP蜂鸣器实验 文章目录 STM32CubeIDE基础学习-BEEP蜂鸣器实验前言第1章 硬件介绍第2章 工程配置2.1 工程外设配置部分2.2 生成工程代码部分 第3章 代码编写第4章 实验现象总结 前言 前面学习了LED闪烁实验&#xff0c;现在来学习一下蜂鸣器发声实验&am…