本文小编为大家详细介绍“Android Flutter怎么在点击事件上添加动画效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android Flutter怎么在点击事件上添加动画效果”文章能帮助大家解决疑惑,下面跟
本文小编为大家详细介绍“Android Flutter怎么在点击事件上添加动画效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android Flutter怎么在点击事件上添加动画效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
底部返回按钮动画其实就是个旋转动画,利用TransfORM.rotate设置angle的值即可,这里使用了GetX来对angle进行动态控制。
//返回键旋转角度,初始旋转45度,使其初始样式为 +var angle = (pi / 4).obs; ///关闭按钮旋转动画控制器late final AnimationController closeController;late final Animation<double> closeAnimation; ///返回键旋转动画closeController = AnimationController( duration: const Duration(milliseconds: 300), vsync: provider,); ///返回键旋转动画closeController = AnimationController( duration: const Duration(milliseconds: 300), vsync: provider,); ///页面渲染完才开始执行,不然第一次打开不会启动动画WidgetsBinding.instance.addPostFrameCallback((duration) { closeAnimation = Tween(begin: pi / 4, end: pi / 2).animate(closeController) ..addListener(() { angle.value = closeAnimation.value; }); closeController.forward();}); ///关闭按钮点击事件void close() { ///反转动画,并关闭页面 Future.delayed( const Duration(milliseconds: 120), () { Get.back(); }); closeController.reverse();} IconButton( onPressed: null, alignment: Alignment.center, icon: Transform.rotate( angle: controller.angle.value, child: SvgPicture.asset( "assets/user/ic-train-car-close.svg", width: 18, height: 18, color: Colors.black, ), ))
四个栏目其实就是个平移动画,只不过闲鱼是四个栏目一起平移,而我选择了变速平移,这样视觉效果上会好一点。
//透明度变化List<AnimationController> opacityControllerList = [];//上移动画,由于每个栏目的移动速度不一样,需要用List保存四个AnimationController,//如果想像闲鱼那种整体上移,则只用一个AnimationController即可。List<AnimationController> offsetControllerList = [];List<Animation<Offset>> offsetAnimationList = []; //之所以用addIf,是因为项目中这几个栏目的显示是动态显示的,这里就直接写成trueColumn( children: [] ..addIf( true, buildItem('assets/user/ic-train-nomal-car.WEBp',"学车加练","自主预约,快速拿证")) ..addIf( true, buildItem('assets/user/ic-train-fuuxn-car.webp',"有证复训","优质陪练,轻松驾车")) ..addIf( true, buildItem('assets/user/ic-train-jiaxun-car.webp',"模拟加训","考前加训,临考不惧")) ..addIf( true, buildItem('assets/user/ic-train-jiakao-car.webp',"驾考报名","快捷报名无门槛")) ..add(playWidget()) ..addAll([ 17.space, ]), ) //仅仅是为了在offsetController全部初始化完后执行play()Widget playWidget() { //执行动画 play(); return Container();} int i = 0; Widget buildItem(String img,String tab,String slogan) { //由于底部栏目是动态显示的,需要在创建Widget时一同创建offsetController和offsetAnimation i++; AnimationController offsetController = AnimationController( duration: Duration(milliseconds: 100 + i * 20), vsync: this, ); Animation<Offset> offsetAnimation = Tween<Offset>( begin: const Offset(0, 2.5), end: const Offset(0, 0), ).animate(CurvedAnimation( parent: offsetController, // curve: Curves.easeInOutSine, curve: const Cubic(0.12, 0.28, 0.48, 1), )); AnimationController opacityController = AnimationController( duration: const Duration(milliseconds: 500), lowerBound: 0.2, upperBound: 1.0, vsync: this); opacityControllerList.add(opacityController); offsetControllerList.add(offsetController); offsetAnimationList.add(offsetAnimation); return SlideTransition( position: offsetAnimation, child: FadeTransition( opacity: opacityController, child: Container( margin: EdgeInsets.only(bottom: 16), height: 62, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12)), color: const Color(0xfffafafa)), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ 24.space, Image.asset(img, width: 44, height: 44), 12.space, Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text(tab, style: const TextStyle( color: Color(0XFF000000), fontSize: 16, fontWeight: FontWeight.bold)), Text(slogan, style: const TextStyle( color: Color(0XFF6e6e6e), fontSize: 12)), ]).expanded, Image.asset("assets/user/ic-train-arrow.webp", width: 44, height: 44), 17.space ])).inkWell( onTap: () {}, delayMilliseconds: 50)), );} //执行动画void play() async { for (int i = 0; i < offsetControllerList.length; i++) { opacityControllerList[i].forward(); ///栏目正序依次延迟(40 + 2 * i) * i的时间,曲线速率 Future.delayed(Duration(milliseconds: (40 + 2 * i) * i), () { offsetControllerList[i] .forward() .whenComplete(() => offsetControllerList[i].stop()); }); }} ///关闭按钮点击事件void close() { ///反转动画,并关闭页面 Future.delayed( const Duration(milliseconds: 120), () { Get.back(); }); for (int i = offsetControllerList.length - 1; i >= 0; i--) { ///栏目倒叙依次延迟(40 + 2 * (offsetControllerList.length-1-i)) * (offsetControllerList.length-1-i))的时间 Future.delayed( Duration( milliseconds: (40 + 2 * (offsetControllerList.length-1-i)) * (offsetControllerList.length-1-i)), () { offsetControllerList[i].reverse(); }); } opacityTopController.reverse();}
渐变动画使用FadeTransition即可。
///图片透明度渐变动画控制器late final AnimationController imGController; ///图片透明度渐变动画imgController = AnimationController( duration: const Duration(milliseconds: 500), lowerBound: 0.0, upperBound: 1.0, vsync: provider);imgController.forward().whenComplete(() => imgController.stop()); ///渐变过渡FadeTransition( opacity: imgController, child: Image.asset("assets/user/ic-traincar-guide.webp"),), ///关闭按钮点击事件void close() { imgController.reverse();}
///顶部标题下移动画控制器late final AnimationController offsetTopController;late final Animation<Offset> offsetTopAnimation; ///顶部标题渐变动画控制器late final AnimationController opacityTopController; ///顶部标题上移动画offsetTopController = AnimationController( duration: const Duration(milliseconds: 300), vsync: provider,);offsetTopController .forward() .whenComplete(() => offsetTopController.stop());offsetTopAnimation = Tween<Offset>( begin: const Offset(0, -0.8), end: const Offset(0, 0),).animate(CurvedAnimation( parent: offsetTopController, curve: Curves.easeInOutCubic,));offsetTopController .forward() .whenComplete(() => offsetTopController.stop()); //UISlideTransition( position: offsetTopAnimation, child: FadeTransition( opacity: opacityTopController, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ 80.space, const Text( '练车指南', style: TextStyle( color: Color(0XFF141414), fontSize: 32, fontWeight: FontWeight.w800, ), ), 2.space, const Text('易练只为您提供优质教练,为您的安全保驾护航', style: TextStyle( color: Color(0XFF141414), fontSize: 15)), ], ))), ///关闭按钮点击事件void close() { offsetTopController.reverse(); opacityTopController.reverse(); }
最后,在关闭页面的时候不要忘记注销动画。
///关闭时注销动画void dispose() { for (int i = offsetControllerList.length - 1; i > 0; i--) { offsetControllerList[i].dispose(); } offsetTopController.dispose(); opacityTopController.dispose(); imgController.dispose(); closeController.dispose();}
读到这里,这篇“Android Flutter怎么在点击事件上添加动画效果”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。
--结束END--
本文标题: Android Flutter怎么在点击事件上添加动画效果
本文链接: https://www.lsjlt.com/news/353465.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0