PR

[Flutter]Flutter Widget of the Week「#25 Align」、「#26 Positioned」、「#27 AnimatedBuilder」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#23 Transform」、「#24 BackdropFilter」を紹介しました。

今回はその続きで「#25 Align」、「#26 Positioned」、「#27 AnimatedBuilder」の3つです。

前回の記事はこちら

Flutter Widget of the Week

環境

  • Flutter 2.10.2

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

#25 Align

Alignとは

親ウィジェットの中で子ウィジェットを好きな位置にレイアウトしたり配置したりするためのウィジェットです。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Align'),
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              const Text('子Widgetの配置を指定'),
              Container(
                width: 100,
                height: 100,
                color: Colors.red[100],
                child: const Align(
                  alignment: Alignment.bottomRight,
                  child: Text('右下'),
                ),
              ),
              const SizedBox(height: 20),
              const Text('Stackと使うと相性が良い'),
              Container(
                width: 300,
                height: 300,
                color: Colors.blue[100],
                child: Stack(
                  children: const [
                    Align(
                      alignment: Alignment.topLeft,
                      child: Text('左上'),
                    ),
                    Align(
                      alignment: Alignment.topCenter,
                      child: Text('中央上'),
                    ),
                    Align(
                      alignment: Alignment.topRight,
                      child: Text('右上'),
                    ),
                    Align(
                      alignment: Alignment.centerLeft,
                      child: Text('左中央'),
                    ),
                    Align(
                      child: Text('中央'),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: Text('右中央'),
                    ),
                    Align(
                      alignment: Alignment.bottomLeft,
                      child: Text('左下'),
                    ),
                    Align(
                      alignment: Alignment.bottomCenter,
                      child: Text('中央下'),
                    ),
                    Align(
                      alignment: Alignment.bottomRight,
                      child: Text('右下'),
                    ),
                    Align(
                      alignment: Alignment(0.4, 0.4),
                      child: Text('数値指定'),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

Stackと組み合わせてウィジェット内の様々な位置に指定できるのがわかります。

動画

公式リファレンス

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

#26 Positioned

Positionedとは

こちらもAlign同様に親ウィジェットの中で子ウィジェットを好きな位置にレイアウトしたり配置したりするためのウィジェットです。

Alignと違う点はPositioned.fillで親ウィジェットすべてを満たすように子ウィジェットをしたり、サイズ指定したりすることができます。Alignではalignmentを指定しますが、Positionedはしていできません。つまりより自由度が大きいです。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Positioned'),
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              const Text('Positioned.fillを使った場合'),
              Container(
                width: 100,
                height: 100,
                color: Colors.red[100],
                child: Stack(
                  children: const [
                    Positioned.fill(
                      child: FlutterLogo(),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 20),
              const Text('配置やサイズの指定もできる'),
              Container(
                width: 300,
                height: 300,
                color: Colors.blue[100],
                child: Stack(
                  children: const [
                    Positioned(
                      left: 100,
                      top: 50,
                      child: FlutterLogo(),
                    ),
                    Positioned(
                      right: 10,
                      bottom: 10,
                      width: 50,
                      height: 50,
                      child: FlutterLogo(),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

Positioned.fillを使うとウィジェット内を満たすように配置されるのがわかります。

配置やサイズ指定できます。

動画

公式リファレンス

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

#27 AnimatedBuilder

AnimatedBuilderとは

アニメーションを与えることAnimatedBuilder内のウィジェットをアニメーションさせることのできるウィジェットです。

AnimatedBuilderを使うにはAnimationControllerやAnimationの知識など必要になってくるので注意が必要です。

サンプルコード

import 'dart:math';

import 'package:flutter/material.dart';

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

  @override
  _SamplePage027State createState() => _SamplePage027State();
}

class _SamplePage027State extends State<SamplePage027>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

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

    _controller = AnimationController(
      duration: const Duration(seconds: 4),
      vsync: this,
    )..repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    final animation = Tween(
      begin: 0,
      end: 2 * pi,
    ).animate(_controller);
    return Scaffold(
      appBar: AppBar(
        title: const Text('AnimatedBuilder'),
      ),
      body: SafeArea(
        child: Center(
          child: AnimatedBuilder(
            animation: animation,
            child: const FlutterLogo(
              size: 100,
            ),
            builder: (context, child) {
              return Transform.rotate(
                angle: animation.value.toDouble(),
                child: child,
              );
            },
          ),
        ),
      ),
    );
  }
}

結果

画像なのでわかりにくいですが、Flutterのロゴが4秒で1回転するようなアニメーションになっています。

動画

公式リファレンス

Page Not Found

さいごに

AlignPositionedは頻繁に使いそうなのでしっかり覚えておきたいですね。

ウィジェットの回転や変形でよく使うのでしっかり覚えておきたいです。

AnimatedBuilderは本格的なアニメーションを自分でどこまで自作するかで難易度が変わりそうです。

おすすめ参考書

リンク

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

コメント

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