FlutterでもLottieを使いたいなと思い、
いろいろ調べたときの備忘録(*´ω`*)
できたのはこんな感じ
進捗です(*´ω`*) pic.twitter.com/L19gqqcpXi
— きらぷか@スプシAPI化&積読のサービス運営中🔥 (@kira_puka) June 8, 2024
使い方
使い方はこんな感じ。表示だけならこれだけでOK
import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:lottie/lottie.dart'; class SimpleLottie extends HookConsumerWidget { const SimpleLottie({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return Lottie.asset('assets/LottieLogo1.json'); } }
終了を検知する
アニメーションの開始、終了をriverpodで扱いたいなと思い、
こんな感じにしたら、よい感じになった
// 表示/非表示のフラグ用のProvider import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'lottie_provider.g.dart'; @Riverpod(keepAlive: true) class Lottie extends _$Lottie { @override bool build() => false; void play() => state = true; void stop() => state = false; }
アニメーションを含むWidgetはこんな感じ。
AnimationController
のaddStatusListener
で、
終了状態を監視する。
// 手動でコントロールするWidget import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:lottie/lottie.dart'; class ManualLottie extends HookConsumerWidget { const ManualLottie({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // AnimationControllerを用意 final controller = useAnimationController(); // statusをlistenして、終了したらflagをOFFにする controller.addStatusListener((status) { if (status == AnimationStatus.completed) { ref.read(lottieProvider.notifier).stop(); } }); // widget自体のdispose時にflagをOFFにする useEffect(() { return () => ref.read(lottieProvider.notifier).stop(); }, const []); return Lottie.asset( 'assets/LottieLogo1.json', repeat: false, controller: controller, onLoaded: (composition) { // 読み込み完了時にdurationを設定 controller.duration = composition.duration; // アニメーションを開始 controller.forward(); }, ); } }
あとは、好きな場所で、lottieProvider
とあわせて指定し、
ref.watch(lottieProvider.notifier).play()
を呼べばOK
class ShowLottie extends HookConsumerWidget { const ShowLottie({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final isShow = ref.watch(lottieProvider); return const Column( children: [ if (isShow) ManualLottie(), ], ); } }
以上!! これでいい感じになった気がする(*´ω`*)