Flutter×Lottie Flutterアプリをワンランクおしゃれにしよう!
目次
1.はじめに
2.サンプル
3.使用パッケージ
4.実装
4-(1)1回だけ動くLottie
4-(2)【応用】PageViewを使用してスライドショーのように使うLottie
5.まとめ
はじめに
Lottieとは、jsonベースのアニメーションファイルです。
簡単に説明しますと、gif画像より軽く、高品質なアニメーションと思っていただけると良いかと思います!
そんなLottieは公式サイトから簡単に素材をダウンロードできますのでお試しください!
それでは早速FlutterでLottieアニメーションを動かしてみましょう!
Lottie公式サイト
サンプル
こちらはシミュレーターを画面録画したGIF画像になりますので、実際にはもっとぬるぬるです!
使用パッケージ
使用するパッケージ
そのままでわかりやすいですね。
実装
コードを書いていきましょう!
-
プロジェクトファイルにassetsにフォルダを作成してダウンロードしたLottieファイル(.json)を配置(URLから呼び出す場合は必要ない)
-
pubspec.yamlのassets設定
assets:
- assets/名前.json
3.FlutterでAssetsからLottieを呼び出す
1回だけ動くLottie
これは公式のUsageにあるものを少しアレンジしたWidgetです。
一回だけ再生されて下のボタンを押すともう一度最初から再生できるものとなっております。
Lottieは基本的にStatefulWidgetをTickerProviderStateMixinで拡張AnimationControllerでコントロールします。
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class SingleShotLottie extends StatefulWidget {
SingleShotLottie({super.key, required this.asset});
final String asset;
@override
State<SingleShotLottie> createState() => _SingleShotLottieState();
}
class _SingleShotLottieState extends State<SingleShotLottie>
with TickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
width: 200,
height: 200,
child: Lottie.asset(
widget.asset,//ここでassetsのパスを直接入力しても良い
controller: _controller,
onLoaded: (composition) {
_controller
..duration = composition.duration
..forward().then((value) => _controller.reset());
},
),
),
ElevatedButton(
onPressed: () {
setState(() {
_controller.forward().then((value) => _controller.reset());
});
},
child: const Text('もう一度みる'))
],
);
}
}
- AnimationControllerのメソッド
forward() => 再生
reset() => 最初に戻る
おそらくこんな感じだと思う
応用 PageViewを使用してスライドショーのようにLottieを使用
PageViewを横にスライドしたタイミングでLottieが再生されるWidgetです。
初回起動時のチュートリアルなんかに使用するとそれっぽく見えていい感じになるかなと思います。
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
final list = ['assets/1.json','assets/2.json','assets/3.json','assets/4.json','assets/5.json','assets/6.json'];//スライドショーに使用したいLottieのassetsパスのリスト
class SlideShowlottie extends StatefulWidget {
const SlideShowlottie(
{super.key,
required this.assetsList,
this.width = 300,
this.height = 300,
this.isBorder = false});
///スライドショーのassetのリスト
final List assetsList;
///スライドショーの幅(デフォルト300)
final double width;
///スライドショーの高さ(デフォルト300)
final double height;
///スライドショーの範囲の枠を表示するかしないか(デフォルトでは表示しない)
final bool isBorder;
@override
_SlideShowlottieState createState() => _SlideShowlottieState();
}
class _SlideShowlottieState extends State<SlideShowlottie>
with TickerProviderStateMixin {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
var controllre = AnimationController(
vsync: this,
//Durationの値で再生から終了までにかかる時間を設定できる。指定なしであれば元々のファイルの再生時間で再生
duration: Duration(seconds: 5));
void startAnimation() {
if (controllre.value == 0) {
controllre.forward().then((value) => controllre.reset());
}
if (controllre.value != 0) {
controllre.reset();
controllre.forward();
}
}
void stopAnimation() {
controllre.stop();
}
var pageController = PageController();
_onChanged(int page) {
startAnimation();
}
startAnimation();
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
border: widget.isBorder ? Border.all(color: Colors.black) : null,
),
child: PageView.builder(
itemCount: widget.assetsList.length,
controller: pageController,
onPageChanged: _onChanged,
itemBuilder: (context, i) {
return LottieTile(
animationController: controllre,
assets: widget.assetsList[i]);
})),
ElevatedButton(
child: const Text('もう一度見る'),
onPressed: () {
startAnimation();
},
),
],
);
}
}
///スライドショーの中に入るタイル
class LottieTile extends StatelessWidget {
const LottieTile(
{super.key, required this.animationController, required this.assets});
final AnimationController animationController;
final String assets;
@override
Widget build(BuildContext context) {
return Center(
child: Lottie.asset(assets, controller: animationController),
);
}
}
まとめ
AnimationControllerを使ったことなくてもなんとなくコピペだけでも動くので比較的簡単に実装できました。
LottieをFlutterで動かすのはそんなに難しくないので、ぜひアプリをワンランク上のものに見せたい時に使用してみてください!
ソースコードはgitにありますので参考にしてみてください!
Discussion