快来领取你的动态春节对联Flutter版实现~

1,017 阅读2分钟

PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

效果

2022-01-17 11.03.17.gif

实现思路

方便起见,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。

效果的整体实现是非常简单的,附上完整代码