Flutter实现点击Play按钮后每隔X秒生成随机位置彩色圆点
Flutter实现定时生成随机颜色随机位置圆点方案
直接上实现方案,核心是用Timer.periodic定时触发更新,配合Random生成随机参数,通过状态管理控制单个圆点的刷新:
实现步骤拆解
- 状态维护:用
StatefulWidget保存当前圆点的位置、颜色,以及定时器实例(用于启停控制) - 随机颜色生成:通过
Random生成0-255范围的红、绿、蓝通道值,再用Color.fromRGBO构造颜色 - 随机位置计算:先获取屏幕可用尺寸,生成在屏幕范围内的随机坐标(注意避开圆点自身尺寸,防止超出屏幕)
- 定时逻辑:点击Play后启动定时器,每隔指定秒数更新圆点的位置和颜色;点击Pause停止定时器,Reset清空圆点
完整代码示例
import 'dart:async'; import 'dart:math'; import 'package:flutter/material.dart'; void main() => runApp(const DotGeneratorApp()); class DotGeneratorApp extends StatelessWidget { const DotGeneratorApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Random Dot Generator', theme: ThemeData(primarySwatch: Colors.blue), home: const DotGeneratorScreen(), ); } } class DotGeneratorScreen extends StatefulWidget { const DotGeneratorScreen({super.key}); @override State<DotGeneratorScreen> createState() => _DotGeneratorScreenState(); } class _DotGeneratorScreenState extends State<DotGeneratorScreen> { final Random _random = Random(); Timer? _timer; // 存储当前圆点的位置和颜色,null表示无圆点 Offset? _dotPosition; Color? _dotColor; // 圆点直径 final double _dotSize = 50; // 定时间隔(秒) final int _intervalSeconds = 2; // 生成随机颜色 Color _generateRandomColor() { return Color.fromRGBO( _random.nextInt(256), _random.nextInt(256), _random.nextInt(256), 1.0, // 不透明 ); } // 生成随机位置 void _generateRandomPosition() { final size = MediaQuery.of(context).size; // 计算可用范围,确保圆点不会超出屏幕 final maxX = size.width - _dotSize; final maxY = size.height - _dotSize - kToolbarHeight; // 减去AppBar高度 setState(() { _dotPosition = Offset( _random.nextDouble() * maxX, _random.nextDouble() * maxY + kToolbarHeight, // 从AppBar下方开始 ); _dotColor = _generateRandomColor(); }); } // 启动定时器 void _startTimer() { if (_timer?.isActive ?? false) return; // 立即生成第一个圆点 _generateRandomPosition(); _timer = Timer.periodic(Duration(seconds: _intervalSeconds), (timer) { _generateRandomPosition(); }); } // 停止定时器 void _stopTimer() { _timer?.cancel(); } // 重置清空圆点 void _reset() { _stopTimer(); setState(() { _dotPosition = null; _dotColor = null; }); } @override void dispose() { _timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Random Dot Generator')), body: Stack( children: [ // 背景占位 const SizedBox.expand(), // 当前显示的圆点 if (_dotPosition != null && _dotColor != null) Positioned( left: _dotPosition!.dx, top: _dotPosition!.dy, child: Container( width: _dotSize, height: _dotSize, decoration: BoxDecoration( color: _dotColor, shape: BoxShape.circle, ), ), ), ], ), bottomNavigationBar: BottomAppBar( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: _startTimer, child: const Text('Play'), ), const SizedBox(width: 16), ElevatedButton( onPressed: _stopTimer, child: const Text('Pause'), ), const SizedBox(width: 16), ElevatedButton( onPressed: _reset, child: const Text('Reset'), ), ], ), ), ); } }
关键说明
- 随机颜色:
_generateRandomColor方法通过Random.nextInt(256)生成0-255的RGB值,确保颜色完全随机 - 位置计算:利用
MediaQuery获取屏幕尺寸,计算时减去圆点自身尺寸和AppBar高度,避免圆点被遮挡或超出屏幕 - 定时器控制:
Timer.periodic会定期触发位置更新,点击Play时先立即生成一个圆点,再开始定时;页面销毁时记得cancel定时器,防止内存泄漏 - 状态更新:每次生成新参数后调用
setState刷新UI,确保只显示最新的单个圆点
内容的提问来源于stack exchange,提问作者Rahul Pandey
相关产品推荐
相关产品推荐

