PR

[Flutter]Flutter Widget of the Week「#58 AlertDialog,CupertinoAlertDialog」、「#59 AnimatedCrossFade」、「#60 DraggableScrollableSheet」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#55 SelectableText」、「#56 DataTable」、「#57 Slider,RangeSlider,CupertinoSlider」を紹介しました。

今回はその続きで「#58 AlertDialog,CupertinoAlertDialog」、「#59 AnimatedCrossFade」、「#60 DraggableScrollableSheet」の3つです。

前回の記事はこちら

Flutter Widget of the Week

環境

  • Flutter 3.0.5

記事にした時点でのバージョンです。GitHubに公開しているのは常に最新の安定版(stable)を使う予定です。

#58 AlertDialog,CupertinoAlertDialog

AlertDialog,CupertinoAlertDialogとは

ユーザーへ警告を出したり、入力を求める際によく使うダイアログを簡単に実装できるウィジェットです。CupertinoAlertDialogはデザインがiOSのデザイン用です。

サンプルコード

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

class SamplePage058 extends StatefulWidget {
  const SamplePage058({
    super.key,
  });

  @override
  State<SamplePage058> createState() => _SamplePage058State();
}

class _SamplePage058State extends State<SamplePage058> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AlertDialog'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () async {
                  await showDialog<bool>(
                    context: context,
                    builder: (context) {
                      return AlertDialog(
                        title: const Text('タイトル'),
                        content: const Text('ここに内容'),
                        actions: [
                          TextButton(
                            onPressed: () {
                              Navigator.of(context).pop(false);
                            },
                            child: const Text('No'),
                          ),
                          TextButton(
                            onPressed: () {
                              Navigator.of(context).pop(true);
                            },
                            child: const Text('Yes'),
                          ),
                        ],
                      );
                    },
                    barrierDismissible: false,
                  );
                },
                child: const Text('AlertDialog'),
              ),
              const SizedBox(height: 30),
              CupertinoButton(
                onPressed: () async {
                  await showCupertinoDialog<bool>(
                    context: context,
                    builder: (context) {
                      return CupertinoAlertDialog(
                        title: const Text('タイトル'),
                        content: const Text('ここに内容'),
                        actions: [
                          CupertinoDialogAction(
                            onPressed: () {
                              Navigator.of(context).pop(false);
                            },
                            child: const Text('No'),
                          ),
                          CupertinoDialogAction(
                            onPressed: () {
                              Navigator.of(context).pop(true);
                            },
                            child: const Text('Yes'),
                          ),
                        ],
                      );
                    },
                    barrierDismissible: false,
                  );
                },
                child: const Text('CupertinoAlertDialog'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

AlertDialog

CupertinoAlertDialog

動画

公式リファレンス

AlertDialog class - material library - Dart API
API docs for the AlertDialog class from the material library, for the Dart programming language.
CupertinoAlertDialog class - cupertino library - Dart API
API docs for the CupertinoAlertDialog class from the cupertino library, for the Dart programming language.

#59 AnimatedCrossFade

AnimatedCrossFadeとは

その名の通り、2つのウィジェットをクロスフェードしながら表示を切り替えるためのウィジェットです。

クロスフェードとは1つはフェードアウト、もう1つをフェードインさせる表示の事を言います。

サンプルコード

import 'package:flutter/material.dart';

class SamplePage059 extends StatefulWidget {
  const SamplePage059({
    super.key,
  });

  @override
  State<SamplePage059> createState() => _SamplePage059State();
}

class _SamplePage059State extends State<SamplePage059> {
  bool _showFirst = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AnimatedCrossFade'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              AnimatedCrossFade(
                firstChild: const CircleAvatar(
                  minRadius: 64,
                  backgroundColor: Colors.blue,
                  child: Text('Hello'),
                ),
                secondChild: const CircleAvatar(
                  minRadius: 64,
                  backgroundColor: Colors.red,
                  child: Text('Goodbye'),
                ),
                crossFadeState: _showFirst
                    ? CrossFadeState.showFirst
                    : CrossFadeState.showSecond,
                duration: const Duration(milliseconds: 500),
              ),
              const SizedBox(height: 30),
              Container(
                padding: const EdgeInsets.all(20),
                color: Colors.green,
              ),
              AnimatedCrossFade(
                firstChild: const CircleAvatar(
                  minRadius: 32,
                  backgroundColor: Colors.blue,
                  child: Text('Hello'),
                ),
                secondChild: const CircleAvatar(
                  minRadius: 64,
                  backgroundColor: Colors.red,
                  child: Text('Goodbye'),
                ),
                layoutBuilder: (
                  topChild,
                  topChildKey,
                  bottomChild,
                  bottomChildKey,
                ) {
                  return Stack(
                    clipBehavior: Clip.none,
                    alignment: Alignment.center,
                    children: [
                      Positioned(
                        key: bottomChildKey,
                        top: 0,
                        child: bottomChild,
                      ),
                      Positioned(
                        key: topChildKey,
                        child: topChild,
                      ),
                    ],
                  );
                },
                crossFadeState: _showFirst
                    ? CrossFadeState.showFirst
                    : CrossFadeState.showSecond,
                duration: const Duration(milliseconds: 500),
              ),
              Container(
                padding: const EdgeInsets.all(20),
                color: Colors.green,
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _showFirst = !_showFirst;
          });
        },
        child: const Icon(Icons.refresh),
      ),
    );
  }
}

結果

動画

公式リファレンス

AnimatedCrossFade class - widgets library - Dart API
API docs for the AnimatedCrossFade class from the widgets library, for the Dart programming language.

#60 DraggableScrollableSheet

DraggableScrollableSheetとは

下からスワイプして表示し、さらにスクロールもできるウィジェットです。

言葉で説明するのは難しいので、結果の画像を見たほうが早いです。

サンプルコード

import 'package:flutter/material.dart';

class SamplePage060 extends StatelessWidget {
  const SamplePage060({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('DraggableScrollableSheet'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Stack(
          children: [
            const Center(
              child: Text('Hello Flutter!'),
            ),
            DraggableScrollableSheet(
              initialChildSize: 0.1,
              minChildSize: 0.1,
              maxChildSize: 0.5,
              builder: (context, scrollController) {
                return DecoratedBox(
                  decoration: const BoxDecoration(
                    color: Colors.grey,
                    borderRadius: BorderRadius.vertical(
                      top: Radius.circular(20),
                    ),
                  ),
                  child: SingleChildScrollView(
                    controller: scrollController,
                    child: Column(
                      children: const [
                        FlutterLogo(
                          size: 256,
                        ),
                        FlutterLogo(
                          size: 256,
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

DraggableScrollableSheet class - widgets library - Dart API
API docs for the DraggableScrollableSheet class from the widgets library, for the Dart programming language.

さいごに

AlertDialogはよく使っていますが、まだまだ知らないウィジェットはたくさんありそうです。

おすすめ参考書

リンク

GitHub - nobushiueshi/flutter_widget_of_the_week
Contribute to nobushiueshi/flutter_widget_of_the_week development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました