当前位置: 首页 > news >正文

flutter 充电气泡

前言:

之前一直看到 有手机充电的时候 有气泡从Type-C 的位置冒泡上来 慢慢上移, 然后和上面的圆圈 会和,感觉还是挺好看的。今天试了下用 Flutter 实现了一版本。大致效果如下,而且气泡 和 气泡直接还可以粘黏

 实现原理:

大致的布局就是这样的: Stack 包裹住所有的元素,需要位置移动的是 AnimatedBuilder,这里是把他们独立出来,方便随机的时候打散处理。

代码实现:

  • PageBubble.dart 整个页面 气泡的粘连效果 有点吃性能
    import 'dart:math';
    import 'dart:ui';import 'package:flutter/material.dart';
    import 'package:untitled1a/pages/example1/bubble_dot.dart';class PageBubble extends StatefulWidget {const PageBubble({Key? key}) : super(key: key);@overrideState<PageBubble> createState() => _PageBubbleState();
    }class _PageBubbleState extends State<PageBubble>with SingleTickerProviderStateMixin {late AnimationController _animationController;final Random random = Random();@overridevoid initState() {_animationController = AnimationController(vsync: this,duration: const Duration(milliseconds: 2500),);_animationController.repeat();super.initState();}@overridevoid dispose() {_animationController.dispose();// TODO: implement disposesuper.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: Text('充电气泡'),),body: Align(alignment: Alignment(0.0, 1),child: Container(height: MediaQuery.of(context).size.height / 3 * 2,width: 250,// color: Colors.blue,child: Stack(alignment: Alignment.topCenter,children: [...buildAnimatedPositioned(),Padding(padding: const EdgeInsets.only(top: 40,left: 0,),child: RotationTransition(alignment: Alignment.center,turns: _animationController,child: Container(width: 200,height: 200,decoration: const BoxDecoration(color: Colors.deepPurple,borderRadius: BorderRadius.only(topRight: Radius.circular(70),topLeft: Radius.circular(90),bottomRight: Radius.circular(60),bottomLeft: Radius.circular(80),),),),),),//这个效果很有意思 就是有费性能  不需要可以移除掉BackdropFilter(filter: ImageFilter.dilate(radiusX: 3.0, radiusY: 3.0),child: Container(),),Positioned(left: 35,top: 45,child: Container(width: 180,height: 180,decoration: BoxDecoration(color: Colors.black,borderRadius: BorderRadius.circular(90),),child: const Center(child: Text('89%',style: TextStyle(fontSize: 40,color: Colors.white,),),),),),],),),),);}int getRandomNumber(int min, int max) {var random = Random();return min + random.nextInt(max - min + 1);}List<Widget> buildAnimatedPositioned() {List<Widget> _list = [];List.generate(9,(index) => {_list.add(BubbleDot(time: getRandomNumber(2000, 3500))),});return _list;}
    }
    

  • BubbleDot.dart    气泡效果    之所以把气泡单独出来是为了后面的随机打散操作
    import 'dart:math';
    import 'package:flutter/material.dart';class BubbleDot extends StatefulWidget {final int time;const BubbleDot({super.key, required this.time});@overrideState<BubbleDot> createState() => _BubbleDotState();
    }class _BubbleDotState extends State<BubbleDot>with SingleTickerProviderStateMixin {late AnimationController _animationController;late Animation<double> _animation;final Random random = Random();late double _leftPos = 0;late double _dotWidth = 0;@overridevoid initState() {_animationController = AnimationController(vsync: this,duration: Duration(milliseconds: widget.time),);_animation = _animationController.drive(Tween<double>(begin: getRandomNumber(660, 800).toDouble(), end: 100));//_leftPos = random.nextDouble() * 200;_leftPos = getRandomNumber(35, 180).toDouble();_dotWidth = getRandomNumber(30, 66).toDouble();_animationController.addStatusListener((AnimationStatus status) => {print('status  $status')});_animationController.repeat();// TODO: implement initStatesuper.initState();}@overridevoid dispose() {// TODO: implement dispose_animationController.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return AnimatedBuilder(animation: _animation,builder: (BuildContext context, Widget? child) {return Positioned(top: _animation.value,//top: 240,left: _leftPos,child: ClipOval(child: Container(width: _dotWidth,height: _dotWidth,decoration: BoxDecoration(color: Colors.deepPurple,boxShadow: [BoxShadow(color: Colors.deepPurple.withOpacity(0.5),spreadRadius: 6,blurRadius: 8,offset: Offset(4, 4), // changes position of shadow),],),),),);},);}int getRandomNumber(int min, int max) {return min + random.nextInt(max - min + 1);}
    }
    

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 安卓系统签名的制作与使用(SignApk.jar)踩坑记录
  • 【Vue3】从零开始编写项目
  • 今日总结:雪花算法,拉取在线用户
  • 深入理解Linux网络(二):UDP接收内核探究
  • tg小程序前端-dogs前端源码分析
  • mongodb数据导出与导入
  • 【20】读感 - 架构整洁之道(二)
  • 基于springboot+vue+uniapp的农场管理系统小程序
  • Yum包下载
  • 【python doris】python连接doris数据库,并查询返回数据框
  • <数据集>pcb板缺陷检测数据集<目标检测>
  • Socket、WebSocket 和 MQTT 的区别
  • c++基础(类和对象中)(类的默认成员函数)
  • 使用Event Sourcing模式管理应用状态
  • c++图的基本操作
  • [iOS]Core Data浅析一 -- 启用Core Data
  • Apache的80端口被占用以及访问时报错403
  • classpath对获取配置文件的影响
  • emacs初体验
  • javascript数组去重/查找/插入/删除
  • maya建模与骨骼动画快速实现人工鱼
  • Meteor的表单提交:Form
  • npx命令介绍
  • spring cloud gateway 源码解析(4)跨域问题处理
  • uni-app项目数字滚动
  • yii2权限控制rbac之rule详细讲解
  • 阿里云前端周刊 - 第 26 期
  • 爱情 北京女病人
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 排序算法学习笔记
  • 七牛云假注销小指南
  • 区块链共识机制优缺点对比都是什么
  • 使用 @font-face
  • 移动端解决方案学习记录
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • ​力扣解法汇总946-验证栈序列
  • #define
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (强烈推荐)移动端音视频从零到上手(下)
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)创业的注意事项
  • (转)使用VMware vSphere标准交换机设置网络连接
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .gitignore不生效的解决方案
  • .Net 4.0并行库实用性演练
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET Core WebAPI中封装Swagger配置
  • .Net Core中的内存缓存实现——Redis及MemoryCache(2个可选)方案的实现
  • .NET 指南:抽象化实现的基类