flutter 充电气泡

打印 上一主题 下一主题

主题 475|帖子 475|积分 1425

媒介:

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

  
  
    实现原理:

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

    代码实现:

  

  • PageBubble.dart 整个页面 气泡的粘连结果 有点吃性能
    1. import 'dart:math';
    2. import 'dart:ui';
    3. import 'package:flutter/material.dart';
    4. import 'package:untitled1a/pages/example1/bubble_dot.dart';
    5. class PageBubble extends StatefulWidget {
    6.   const PageBubble({Key? key}) : super(key: key);
    7.   @override
    8.   State<PageBubble> createState() => _PageBubbleState();
    9. }
    10. class _PageBubbleState extends State<PageBubble>
    11.     with SingleTickerProviderStateMixin {
    12.   late AnimationController _animationController;
    13.   final Random random = Random();
    14.   @override
    15.   void initState() {
    16.     _animationController = AnimationController(
    17.       vsync: this,
    18.       duration: const Duration(milliseconds: 2500),
    19.     );
    20.     _animationController.repeat();
    21.     super.initState();
    22.   }
    23.   @override
    24.   void dispose() {
    25.     _animationController.dispose();
    26.     // TODO: implement dispose
    27.     super.dispose();
    28.   }
    29.   @override
    30.   Widget build(BuildContext context) {
    31.     return Scaffold(
    32.       appBar: AppBar(
    33.         backgroundColor: Theme.of(context).colorScheme.inversePrimary,
    34.         title: Text('充电气泡'),
    35.       ),
    36.       body: Align(
    37.         alignment: Alignment(0.0, 1),
    38.         child: Container(
    39.           height: MediaQuery.of(context).size.height / 3 * 2,
    40.           width: 250,
    41.           // color: Colors.blue,
    42.           child: Stack(
    43.             alignment: Alignment.topCenter,
    44.             children: [
    45.               ...buildAnimatedPositioned(),
    46.               Padding(
    47.                 padding: const EdgeInsets.only(
    48.                   top: 40,
    49.                   left: 0,
    50.                 ),
    51.                 child: RotationTransition(
    52.                   alignment: Alignment.center,
    53.                   turns: _animationController,
    54.                   child: Container(
    55.                     width: 200,
    56.                     height: 200,
    57.                     decoration: const BoxDecoration(
    58.                       color: Colors.deepPurple,
    59.                       borderRadius: BorderRadius.only(
    60.                         topRight: Radius.circular(70),
    61.                         topLeft: Radius.circular(90),
    62.                         bottomRight: Radius.circular(60),
    63.                         bottomLeft: Radius.circular(80),
    64.                       ),
    65.                     ),
    66.                   ),
    67.                 ),
    68.               ),
    69.               //这个效果很有意思 就是有费性能  不需要可以移除掉
    70.               BackdropFilter(
    71.                 filter: ImageFilter.dilate(radiusX: 3.0, radiusY: 3.0),
    72.                 child: Container(),
    73.               ),
    74.               Positioned(
    75.                 left: 35,
    76.                 top: 45,
    77.                 child: Container(
    78.                   width: 180,
    79.                   height: 180,
    80.                   decoration: BoxDecoration(
    81.                     color: Colors.black,
    82.                     borderRadius: BorderRadius.circular(90),
    83.                   ),
    84.                   child: const Center(
    85.                     child: Text(
    86.                       '89%',
    87.                       style: TextStyle(
    88.                         fontSize: 40,
    89.                         color: Colors.white,
    90.                       ),
    91.                     ),
    92.                   ),
    93.                 ),
    94.               ),
    95.             ],
    96.           ),
    97.         ),
    98.       ),
    99.     );
    100.   }
    101.   int getRandomNumber(int min, int max) {
    102.     var random = Random();
    103.     return min + random.nextInt(max - min + 1);
    104.   }
    105.   List<Widget> buildAnimatedPositioned() {
    106.     List<Widget> _list = [];
    107.     List.generate(
    108.         9,
    109.         (index) => {
    110.               _list.add(BubbleDot(time: getRandomNumber(2000, 3500))),
    111.             });
    112.     return _list;
    113.   }
    114. }
    复制代码

  • BubbleDot.dart    气泡结果    之所以把气泡单独出来是为了后面的随机打散操纵
    1. import 'dart:math';
    2. import 'package:flutter/material.dart';
    3. class BubbleDot extends StatefulWidget {
    4.   final int time;
    5.   const BubbleDot({super.key, required this.time});
    6.   @override
    7.   State<BubbleDot> createState() => _BubbleDotState();
    8. }
    9. class _BubbleDotState extends State<BubbleDot>
    10.     with SingleTickerProviderStateMixin {
    11.   late AnimationController _animationController;
    12.   late Animation<double> _animation;
    13.   final Random random = Random();
    14.   late double _leftPos = 0;
    15.   late double _dotWidth = 0;
    16.   @override
    17.   void initState() {
    18.     _animationController = AnimationController(
    19.       vsync: this,
    20.       duration: Duration(milliseconds: widget.time),
    21.     );
    22.     _animation = _animationController.drive(
    23.         Tween<double>(begin: getRandomNumber(660, 800).toDouble(), end: 100));
    24.     //_leftPos = random.nextDouble() * 200;
    25.     _leftPos = getRandomNumber(35, 180).toDouble();
    26.     _dotWidth = getRandomNumber(30, 66).toDouble();
    27.     _animationController.addStatusListener(
    28.         (AnimationStatus status) => {print('status  $status')});
    29.     _animationController.repeat();
    30.     // TODO: implement initState
    31.     super.initState();
    32.   }
    33.   @override
    34.   void dispose() {
    35.     // TODO: implement dispose
    36.     _animationController.dispose();
    37.     super.dispose();
    38.   }
    39.   @override
    40.   Widget build(BuildContext context) {
    41.     return AnimatedBuilder(
    42.       animation: _animation,
    43.       builder: (BuildContext context, Widget? child) {
    44.         return Positioned(
    45.           top: _animation.value,
    46.           //top: 240,
    47.           left: _leftPos,
    48.           child: ClipOval(
    49.             child: Container(
    50.               width: _dotWidth,
    51.               height: _dotWidth,
    52.               decoration: BoxDecoration(
    53.                 color: Colors.deepPurple,
    54.                 boxShadow: [
    55.                   BoxShadow(
    56.                     color: Colors.deepPurple.withOpacity(0.5),
    57.                     spreadRadius: 6,
    58.                     blurRadius: 8,
    59.                     offset: Offset(4, 4), // changes position of shadow
    60.                   ),
    61.                 ],
    62.               ),
    63.             ),
    64.           ),
    65.         );
    66.       },
    67.     );
    68.   }
    69.   int getRandomNumber(int min, int max) {
    70.     return min + random.nextInt(max - min + 1);
    71.   }
    72. }
    复制代码

  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曹旭辉

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表