PR

[Flutter]Flutter Widget of the Week「#34 MediaQuery」、「#35 Spacer」、「#36 InheritedWidget」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#31 Draggable」、「#32 AnimatedList」、「#33 Flexible」を紹介しました。

今回はその続きで「#34 MediaQuery」、「#35 Spacer」、「#36 InheritedWidget」の3つです。

前回の記事はこちら

Flutter Widget of the Week

環境

  • Flutter 2.10.3

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

#34 MediaQuery

MediaQueryとは

MediaQueryを利用することで、使用しているデバイスのサイズやユーザー設定に関する情報を取得することができます。

以前やったLayoutBuilderでも大きさ等知ることができましたが、MediaQueryのほうが多くの情報を知ることができます。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  State<SamplePage034> createState() => _SamplePage034State();
}

class _SamplePage034State extends State<SamplePage034> {
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final orientation = MediaQuery.of(context).orientation;
    final textScaleFactor = MediaQuery.of(context).textScaleFactor;
    return Scaffold(
      appBar: AppBar(
        title: const Text('MediaQuery'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              Text('size : $size'),
              Text('orientation : $orientation'),
              Text('textScaleFactor : $textScaleFactor'),
            ],
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

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

#35 Spacer

Spacerとは

RowやColumnにあるAlignmentのspaceAround, spaceBetween, spaceEvenlyでも配置したものにスペースを空けることができますが、Spacerを使うことでスペースの位置をよりカスタマイズできるようになります。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Spacer'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              Row(
                children: const [
                  _SamplePage035ColorBox(),
                  Spacer(),
                  _SamplePage035ColorBox(),
                  Spacer(),
                  _SamplePage035ColorBox(),
                ],
              ),
              const SizedBox(height: 20),
              Row(
                children: const [
                  _SamplePage035ColorBox(),
                  Spacer(flex: 2),
                  _SamplePage035ColorBox(),
                  Spacer(),
                  _SamplePage035ColorBox(),
                ],
              ),
              const SizedBox(height: 20),
              Row(
                children: const [
                  _SamplePage035ColorBox(),
                  Spacer(),
                  _SamplePage035ColorBox(),
                  Spacer(flex: 3),
                  _SamplePage035ColorBox(),
                  Spacer(flex: 9),
                  _SamplePage035ColorBox(),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

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

  final Color color;

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

結果

動画

公式リファレンス

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

#36 InheritedWidget

InheritedWidgetとは

InheritedWidgetはFlutterの状態管理でよく使われるウィジェットです。InheritedWidgetを使うことで簡単に子ウィジェットや孫ウィジェット等から祖先のウィジェットの状態の値を取得することができるようになります。

ただし、InheritedWidgetを単体で利用するとコードが複雑になりがちなので、providerScopedModel等の管理パッケージを利用することをおすすめします。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  State<SamplePage036> createState() => _SamplePage036State();
}

class _SamplePage036State extends State<SamplePage036> {
  var _color = Colors.white;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('InheritedWidget'),
        centerTitle: true,
      ),
      body: _SamplePage036Color(
        color: _color,
        child: SafeArea(
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  ElevatedButton(
                    onPressed: () {
                      setState(() {
                        _color = Colors.blue;
                      });
                    },
                    style: ElevatedButton.styleFrom(
                      primary: Colors.blue,
                    ),
                    child: const Text('Blue'),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      setState(() {
                        _color = Colors.yellow;
                      });
                    },
                    style: ElevatedButton.styleFrom(
                      primary: Colors.yellow,
                    ),
                    child: const Text('Yellow'),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      setState(() {
                        _color = Colors.red;
                      });
                    },
                    style: ElevatedButton.styleFrom(
                      primary: Colors.red,
                    ),
                    child: const Text('Red'),
                  ),
                ],
              ),
              const SizedBox(height: 100),
              const _SamplePage036Child(),
            ],
          ),
        ),
      ),
    );
  }
}

class _SamplePage036Color extends InheritedWidget {
  const _SamplePage036Color({
    Key? key,
    required this.color,
    required Widget child,
  }) : super(
          key: key,
          child: child,
        );

  final Color color;

  static _SamplePage036Color of(BuildContext context) {
    final result =
        context.dependOnInheritedWidgetOfExactType<_SamplePage036Color>();
    assert(result != null, 'No _SamplePage036Color found in context');
    return result!;
  }

  @override
  bool updateShouldNotify(covariant _SamplePage036Color oldWidget) =>
      color != oldWidget.color;
}

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

  @override
  Widget build(BuildContext context) {
    final color = _SamplePage036Color.of(context).color;
    return Container(
      width: 100,
      height: 100,
      color: color,
    );
  }
}

結果

動画

公式リファレンス

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

さいごに

MediaQuerySpacerは確実に覚えておきたいですね。

InheritedWidgetは状態管理で使っている場合は覚えておきたいですね。

おすすめ参考書

リンク

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

コメント

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