0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Flutter 画面初期表示時にウィジェットをフェードインさせたい

Posted at

ボタン押下時にフェードインさせる情報はいくつか見つかったものの、初期表示時の情報は見つけられなかったのでメモ。

実現したいこと

画面の初期表示時に特定のウィジェットをフェードインで表示させたい。
AnimationControllerは使わず簡単に実装したい。

実現方法

フェードインさせたいウィジェットをAnimatedOpacityでラップし、画面ビルド後にopacity値(不透明度)を0から1に変化させる。

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

/// opacityの変化を監視できるようにするためのStateProvider
final opacityProvider = StateProvider.autoDispose<double>((ref) {
  // opacityの初期値
  return 0;
});

/// フェードインウィジェットがあるページ
class SamplePage extends ConsumerWidget {
  const SamplePage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 不透明度の変化を監視
    final opacity = ref.watch(opacityProvider);

    WidgetsBinding.instance.addPostFrameCallback(
      (timeStamp) async {
        // ビルド後に実行されるコールバック関数
        // 監視中のopacityを1に更新
        ref.read(opacityProvider.notifier).state = 1;
      },
    );

    return Scaffold(
      appBar: AppBar(
        title: const Text('AnimatedOpacity Demo'),
        centerTitle: true,
      ),
      body: AnimatedOpacity(
        // 不透明度
        opacity: opacity,
        // フェードイン完了までの間隔
        duration: const Duration(seconds: 1),
        // フェードインさせるウィジェット
        child: Center(
          child: Container(
            color: Colors.blue,
            height: 300,
            width: 300,
          ),
        ),
      ),
    );
  }
}

/// 遷移ボタンのページ
class SamplePage2 extends StatelessWidget {
  const SamplePage2({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: OutlinedButton(
          onPressed: () => Navigator.of(context).push(
            // フェードイン以外のアニメーションがあるとわかりにくいのでオフ
            PageRouteBuilder(
              pageBuilder: (_, __, ___) => const SamplePage(),
              transitionDuration: const Duration(seconds: 0),
            ),
          ),
          child: const Text('フェードインページに遷移します'),
        ),
      ),
    );
  }
}

screen-recording-20240414-015011.gif

なぜビルド後に変化させなければならないか?

AnimatedOpacityが、opacityの値が変化したときにアニメーションで切り替わるウィジェットだから。

Animated version of Opacity which automatically transitions the child's opacity over a given duration whenever the given opacity changes.

Google翻訳:指定された不透明度が変化するたびに、指定された期間にわたって子の不透明度を自動的に遷移させる Opacity のアニメーション バージョン。

フェードインさせたい場合は、一度 opacity: 0 → 1 の変化を経ないといけないわけですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?