PR

[Flutter]Flutter Widget of the Week「#46 IndexedStack」、「#47 Semantics」、「#48 ConstrainedBox」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#43 AnimatedSwitcher」、「#44 AnimatedPositioned」、「#45 AnimatedPadding」を紹介しました。

今回はその続きで「#46 IndexedStack」、「#47 Semantics」、「#48 ConstrainedBox」の3つです。

前回の記事はこちら

Flutter Widget of the Week

環境

  • Flutter 3.0.4

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

#46 IndexedStack

IndexedStackとは

状態を保持しつつウィジェットを入れ替えたいときに、IndexedStackウィジェットを利用します。

BottomNavigationと組み合わせて使うことがよくあります。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  State<SamplePage046> createState() => _SamplePage046State();
}

class _SamplePage046State extends State<SamplePage046> {
  var _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('IndexedStack'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: IndexedStack(
          index: _currentIndex,
          children: const [
            _SamplePage046Child(
              text: 'Home',
            ),
            _SamplePage046Child(
              text: 'Settings',
            ),
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            label: 'Settings',
          ),
        ],
        currentIndex: _currentIndex,
        onTap: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

class _SamplePage046Child extends StatefulWidget {
  const _SamplePage046Child({
    required this.text,
  });

  final String text;

  @override
  State<_SamplePage046Child> createState() => _SamplePage046ChildState();
}

class _SamplePage046ChildState extends State<_SamplePage046Child> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                widget.text,
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        heroTag: widget.text,
        child: const Icon(Icons.add),
        onPressed: () {
          setState(() {
            _counter += 1;
          });
        },
      ),
    );
  }
}

結果

動画

公式リファレンス

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

#47 Semantics

Semanticsとは

ウィジェットのUIの部分が何を意味するかを示すためのウィジェットです。

スクリーンリーダーや検索エンジンや他のセマンティックな検証ツールに知らせるためのものらしいです。

。。。らしいと言ったのは正直、これがどう役に立つのかはFlutterをモバイル開発でしか使ったことのない筆者にはまったくわかりませんでした。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Semantics'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Semantics(
            label: 'Flutter Logo',
            image: true,
            enabled: true,
            child: const FlutterLogo(
              size: 128,
            ),
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

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

#48 ConstrainedBox

ConstrainedBoxとは

ウィジェットの幅や高さなどに最小値や最大値などの制限をつけることができるウィジェットです。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('ConstrainedBox'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text('ConstrainedBoxで制限がない場合'),
              const SizedBox(height: 10),
              const Text(
                'Delicious Candy',
                textAlign: TextAlign.center,
              ),
              ElevatedButton(
                onPressed: () {},
                child: const Text('Tap Me!'),
              ),
              const SizedBox(height: 30),
              const Text('ConstrainedBoxで制限がある場合'),
              const SizedBox(height: 10),
              ConstrainedBox(
                constraints: const BoxConstraints(
                  maxWidth: 100,
                ),
                child: const Text(
                  'Delicious Candy',
                  textAlign: TextAlign.center,
                ),
              ),
              ConstrainedBox(
                constraints: const BoxConstraints(
                  minHeight: 100,
                ),
                child: ElevatedButton(
                  onPressed: () {},
                  child: const Text('Tap Me!'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

BoxConstraints class - rendering library - Dart API
API docs for the BoxConstraints class from the rendering library, for the Dart programming language.

さいごに

Semanticってどういう時に役立つのだろうか。。。

おすすめ参考書

リンク

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

コメント

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