PR

[Flutter]Flutter Widget of the Week「#37 AnimatedIcon」、「#38 AspectRatio」、「#39 LimitedBox」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#34 MediaQuery」、「#35 Spacer」、「#36 InheritedWidget」を紹介しました。

今回はその続きで「#37 AnimatedIcon」、「#38 AspectRatio」、「#39 LimitedBox」の3つです。

前回の記事はこちら

Flutter Widget of the Week

環境

  • Flutter 2.10.3

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

#37 AnimatedIcon

AnimatedIconとは

名前の通りアイコンのアニメーションがある版です。

アニメーション用の設定をいちいちしなければいけないので、リッチなUIを目指さないのであればあまり活用する場面はなさそうな印象です。

サンプルコード

import 'package:flutter/material.dart';

class SamplePage037 extends StatefulWidget {
  const SamplePage037({
    Key? key,
  }) : super(key: key);

  @override
  State<SamplePage037> createState() => _SamplePage037State();
}

class _SamplePage037State extends State<SamplePage037>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  bool _status = false;

  @override
  void initState() {
    super.initState();

    _animationController = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AnimatedIcon'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              AnimatedIcon(
                icon: AnimatedIcons.pause_play,
                progress: _animationController,
              ),
              const SizedBox(height: 20),
              AnimatedIcon(
                icon: AnimatedIcons.close_menu,
                progress: _animationController,
              ),
              const SizedBox(height: 20),
              AnimatedIcon(
                icon: AnimatedIcons.list_view,
                progress: _animationController,
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          if (!_status) {
            _animationController.forward();
          } else {
            _animationController.reverse();
          }
          setState(() {
            _status = !_status;
          });
        },
        child: const Icon(Icons.replay),
      ),
    );
  }
}

結果

アニメーションしながらアイコンが変わります。

動画

公式リファレンス

AnimatedIcon class - material library - Dart API
API docs for the AnimatedIcon class from the material library, for the Dart programming language.

#38 AspectRatio

AspectRatioとは

ウィジェットを画面の比率等で制御したい場合に活用するウィジェットです。

aspectRatioを分数で設定するとわかりやすいです。「3 / 1」なら「3 : 1」になります。

サンプルコード

import 'package:flutter/material.dart';

class SamplePage038 extends StatelessWidget {
  const SamplePage038({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AspectRatio'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            children: const [
              AspectRatio(
                aspectRatio: 3 / 1,
                child: _SamplePage038Child(),
              ),
              Expanded(
                child: Align(
                  alignment: Alignment.bottomCenter,
                  child: AspectRatio(
                    aspectRatio: 3 / 1,
                    child: _SamplePage038Child(
                      color: Colors.red,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SamplePage038Child extends StatelessWidget {
  const _SamplePage038Child({
    Key? key,
    this.color = Colors.blue,
  }) : super(key: key);

  final Color color;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
    );
  }
}

結果

縦向き

横向き

動画

公式リファレンス

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

#39 LimitedBox

LimitedBoxとは

ウィジェットの最大の幅と高さを決めることができます。親ウィジェットが子ウィジェットのサイズ指定しない場合に活躍するウィジェットです。

また、親ウィジェットにサイズ制限がある場合はそちらが優先されます。

サンプルコード

import 'package:flutter/material.dart';

class SamplePage039 extends StatelessWidget {
  const SamplePage039({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('LimitedBox'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text('LimitedBoxなし'),
            Expanded(
              child: ListView(
                shrinkWrap: true,
                children: [
                  for (var i = 0; i < 10; i++)
                    Container(
                      color: i.isEven ? Colors.blue : Colors.red,
                    ),
                ],
              ),
            ),
            const Divider(),
            const Text('LimitedBoxあり'),
            Expanded(
              child: ListView(
                children: [
                  for (var i = 0; i < 10; i++)
                    LimitedBox(
                      maxHeight: 100,
                      child: Container(
                        color: i.isEven ? Colors.blue : Colors.red,
                      ),
                    ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

結果

LimitedBoxありなしでこんなかんじで差があります。

動画

公式リファレンス

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

さいごに

AspectRatioLimitedBoxは使うことがありそうなので、確実に覚えておきたいですね。

AnimatedIconはできたら覚えておくくらいですかね。

おすすめ参考書

リンク

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

コメント

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