建设工程中标查询网站seo关键词优化哪个平台好
在Android App的开发项目中,我们需要在点击事件上实现一个动画效果来提高用户的体验度。比如闲鱼底部中间按钮的那种。该怎么实现呢? 一起来看看吧
实现效果如图:
实现思路
根据UI的设计图,对每个模块设计好动画效果,需要实现以下四个效果。
1、底部返回键旋转动画
底部返回按钮动画其实就是个旋转动画,利用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,),))
2、底部四个栏目变速上移动画+渐变动画
四个栏目其实就是个平移动画,只不过闲鱼是四个栏目一起平移,而我选择了变速平移,这样视觉效果上会好一点。
//透明度变化
List<AnimationController> opacityControllerList = [];
//上移动画,由于每个栏目的移动速度不一样,需要用List保存四个AnimationController,
//如果想像闲鱼那种整体上移,则只用一个AnimationController即可。
List<AnimationController> offsetControllerList = [];
List<Animation<Offset>> offsetAnimationList = [];//之所以用addIf,是因为项目中这几个栏目的显示是动态显示的,这里就直接写成true
Column(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和offsetAnimationi++;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();
}
3、中间图片渐变动画
渐变动画使用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();
}
4、顶部文案渐变动画+下移动画
///顶部标题下移动画控制器
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());//UI
SlideTransition(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();}
5、注销动画
最后,在关闭页面的时候不要忘记注销动画。
///关闭时注销动画
void dispose() {for (int i = offsetControllerList.length - 1; i > 0; i--) {offsetControllerList[i].dispose();}offsetTopController.dispose();opacityTopController.dispose();imgController.dispose();closeController.dispose();
}
以上就是Android Flutter实现仿闲鱼动画效果的详细内容,更多关于Android Flutter知识可以参考
Android Futtter学习文档