PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛
效果
实现思路
方便起见,demo只是写死了几组对联,每次获取对联数据时,在0-4之间随机生成一个数字,这样保证每次显示的对联是随机的。 布局非常简单,这里面的上下联垂直文字实现比较另类😆,就是限制宽度固定,使得每行只能显示下一个文字,这样就可以实现文字自动换行的效果。
Container(
width: 70,
height: _downAnimationController.value * 420,
alignment: Alignment.center,
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
color: const Color(0xffc62c21),
child: Text(
_downList[randomNum],
maxLines: 999,
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: "kaiti",
height: 1.5,
fontSize: 35,
fontWeight: FontWeight.bold),
),
),
AnimatedOpacity(
duration: const Duration(milliseconds: 1000),
opacity: _showFu ? 1 : 0,
child: Image.asset(
"assets/images/fu.png",
width: 120,
height: 120,
),
),
],
),
);
}
上下联的动画是使用AnimationController
动画控制器来动态更新上下联布局高度和横批布局宽度,而中间福字的渐变动画是使用AnimatedOpacity
组件实现。那么为了要完成上下联、横批、福字接连显示的动态效果,关键点就是:首先先让上联动画控制器开始播放,在此动画监听中通过animationController.isCompleted
方法来判断上联动画是否完成,完成后继续调用下联控制器的forward
方法开启下联动画。同理,监听下联动画时再开启横批的动画,而上联动画完成后改变控制福字透明度的字段为true,刷新布局致使福字以渐变的方式显示出来。
_downAnimationController =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
_downAnimationController.addListener(() {
// 下联动画完成开始横批动画
if (_downAnimationController.isCompleted) {
_horizontalAnimationController.forward();
}
setState(() {});
});
_upAnimationController =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
_upAnimationController.addListener(() {
// 上联动画完成开始下联动画
if (_upAnimationController.isCompleted) {
_downAnimationController.forward();
}
setState(() {});
});
_upAnimationController.forward();
_horizontalAnimationController =
AnimationController(duration: const Duration(seconds: 2), vsync: this);
_horizontalAnimationController.addListener(() {
// 横批动画完成开始显示福字
if (_horizontalAnimationController.isCompleted) {
_showFu = true;
}
setState(() {});
});
修改字体及加入音乐
修改字体需要找到自己想要的字体包,放入到assets目录下,同时在pubspec.yaml中声明使用,然后在引用时给Text组件的style属性中的fontfamily指定对应的字体名称即可。
fonts:
- family: kaiti
fonts:
- asset: assets/fonts/kaiti.ttf
TextStyle(
fontFamily: "kaiti",
height: 1.5,
fontSize: 35,
fontWeight: FontWeight.bold)
引入本地音乐,需要把mp3音乐文件放入到assets目录下,同样也需要在pubspec.yaml中声明使用,这里播放音频使用的是插件:audioplayers: ^0.20.1
,在使用时首先初始化AudioCache
对象,然后调用其play或loop方法进行播放即可。
AudioCache player = AudioCache();
player.loop('sounds/bg.mp3');
注意这里文件路径已经默认带有assets文件夹,所以无需再拼接assets。
效果的整体实现是非常简单的,附上完整代码