在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。

本文章实现的效果如下图所示:

Flutter 雪花飘落的效果-深夜创作_Flutter学习

/// 程序入口
void main() {
runApp(
MaterialApp(
//不显示debug标签
debugShowCheckedModeBanner: false,
//默认显示的首页面
home: TestPage(),
),
);
}

首先来一个全局获取随机透明度的白色颜色的方法​,用来​生成雪花使用的不同的白色:​

//全局定义获取颜色的方法
Color getRandomWhiteColor(Random random) {
//透明度 0 ~ 200 255是不透明
int a = random.nextInt(200);
return Color.fromARGB(a, 255, 255, 255);
}

定义 雪花模型 用来保存雪花的基本属性信息:

///定义 雪花模型 用来保存雪花的基本属性信息
class BobbleBean {
//位置
Offset postion;

//初始位置
Offset origin;
//颜色
Color color;
//运动的速度
double speed;
//半径
double radius;
}

/// 雪花背景
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> with TickerProviderStateMixin {
//创建一个集合用来保存气泡
List<BobbleBean> _list = [];

//随机数
Random _random = new Random(DateTime.now().microsecondsSinceEpoch);

//来个动画控制器
AnimationController _animationController;

//初始化函数中创建气泡
@override
void initState() {
super.initState();

Future.delayed(Duration.zero, () {
initData();
});

//创建动画控制器 1秒
_animationController = new AnimationController(
vsync: this, duration: Duration(milliseconds: 10000));

//执行刷新监听
_animationController.addListener(() {
setState(() {});
});
//开启气泡的运动
_animationController.repeat();

// 状态栏隐藏
SystemChrome.setEnabledSystemUIOverlays([]);
}

void initData() {
for (int i = 0; i < 2000; i++) {
BobbleBean bean = new BobbleBean();
//获取随机透明度白色
bean.color = getRandomWhiteColor(_random);
//设置位置 先来个默认的 绘制的时候再修改
double x = _random.nextDouble() * MediaQuery.of(context).size.width;
double y = _random.nextDouble() * MediaQuery.of(context).size.height;
double z = _random.nextDouble() + 0.5;
bean.speed = _random.nextDouble() + 0.01 / z;
bean.postion = Offset(x, y);
bean.origin = Offset(x, 0);
//设置半径
bean.radius = 2.0 / z;

_list.add(bean);
}
}

... ...

}

页面 UI 的构建方法如下:


@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,

///填充布局
body: Container(
width: double.infinity,
height: double.infinity,
//层叠布局
child: Stack(
children: [
//第一部分 背景
Positioned.fill(
child: Image.asset(
"assets/images/bg_snow.png",
fit: BoxFit.fill,
),
),
//第二部分 雪花
CustomPaint(
size: MediaQuery.of(context).size,
//画布
painter: SnowCustomMyPainter(list: _list, random: _random),
),
],
),
),
);
}

自定义画布如下:

///创建画布
class SnowCustomMyPainter extends CustomPainter {
List<BobbleBean> list;
Random random;

SnowCustomMyPainter({this.list, this.random});

//先来个画笔
Paint _paint = new Paint()..isAntiAlias = true;
//具体的绘制功能
@override
void paint(Canvas canvas, Size size) {
// 在绘制前重新计算每个点的位置
list.forEach((element) {
//左右微抖动
double dx = random.nextDouble() * 2.0 - 1.0;
//竖直方向位置偏移
double dy = element.speed;
//位置偏移量计算
element.postion += Offset(dx, dy);

//重置位置
if (element.postion.dy > size.height) {
element.postion = element.origin;
}

});
//
// //绘制
list.forEach((element) {
//修改画笔的颜色
_paint.color = element.color;
//绘制圆
canvas.drawCircle(element.postion, element.radius, _paint);
});
}

//刷新 控制
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
//返回false 不刷新
return true;
}
}

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过 文章底部扫码关注

​【x2】各种系列的视频教程 免费开源 关注 你不会迷路​

​【x3】系列文章 百万 Demo 随时 复制粘贴 使用​

​【x4】简短的视频不一样的体验​

​【x5】必须有源码​


Flutter 雪花飘落的效果 冬秋的延续 雪是冬的足迹 我们共同努力


不局限于思维,不局限语言限制,才是编程的最高境界。

以小编的性格,肯定是要录制一套视频的,随后会上传

有兴趣 你可以关注一下 ​​西瓜视频 — 早起的年轻人​

Flutter 雪花飘落的效果-深夜创作_Flutter教程_02