PR

[Flutter]Flutter Widget of the Week「#157 SegmentedButton」、「#158 Isolates」、「#159 Tween」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#154 OverlayPortal」、「#155 DropdownMenu」、「#156 feedback」を紹介しました。

今回はその続きで「#157 SegmentedButton」、「#158 Isolates」、「#159 Tween」の3つです。

前回の記事はこちら

またGitHubにも公開しています。

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

Flutter Widget of the Week

環境

  • Flutter 3.19.6

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

#157 SegmentedButton

SegmentedButtonとは?

ユーザーに対しオプションを選択させるようなUIにおすすめなWidgetです。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  State<SamplePage157> createState() => _SamplePage157State();
}

class _SamplePage157State extends State<SamplePage157> {
  Set<String> _multiSelected = {'Inbox'};
  Set<String> _selected = {'Inbox'};

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SegmentedButton'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text('multiSelectionEnabled: true'),
              const SizedBox(height: 20),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: SegmentedButton(
                  multiSelectionEnabled: true,
                  segments: const [
                    ButtonSegment<String>(
                      value: 'Inbox',
                      label: Text('Inbox'),
                    ),
                    ButtonSegment<String>(
                      value: 'Primary',
                      label: Text('Primary'),
                    ),
                    ButtonSegment<String>(
                      value: 'Everything Else',
                      label: Text('Everything Else'),
                    ),
                  ],
                  selected: _multiSelected,
                  onSelectionChanged: (newSelection) {
                    setState(() {
                      _multiSelected = newSelection;
                    });
                  },
                ),
              ),
              const SizedBox(height: 80),
              const Text('multiSelectionEnabled: false'),
              const SizedBox(height: 20),
              SegmentedButton(
                segments: const [
                  ButtonSegment<String>(
                    value: 'Inbox',
                    icon: Icon(Icons.inbox_outlined),
                  ),
                  ButtonSegment<String>(
                    value: 'Primary',
                    icon: Icon(Icons.priority_high_outlined),
                  ),
                  ButtonSegment<String>(
                    value: 'Everything Else',
                    icon: Icon(Icons.web_stories_outlined),
                  ),
                ],
                selected: _selected,
                onSelectionChanged: (newSelection) {
                  setState(() {
                    _selected = newSelection;
                  });
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

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

#158 Isolates

Isolatesとは?

Flutterのアプリは通常、UIスレッドと呼ばれる単一のスレッドで実行されます。

もしコードの処理に時間がかかりすぎると画面のフレームレートが落ちて、カクカクした動作に見えてしまいます。

そこで重い処理などはIsolatesと呼ばれるスレッドで処理することでフレームレートを落とすことなくコードを実行できるようになります。

サンプルコード

import 'dart:convert';

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

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

  @override
  State<SamplePage158> createState() => _SamplePage158State();
}

class _SamplePage158State extends State<SamplePage158> {
  final jsonString = '{"message":"Hello, World!"}';

  String message = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Isolates'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(message),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final data = await compute(loadJson, jsonString);
          setState(() {
            message = data.message;
          });
        },
        child: const Icon(Icons.refresh_outlined),
      ),
    );
  }
}

SamplePage158Message loadJson(String jsonString) {
  // ここで重い処理を実行する.
  final json = jsonDecode(jsonString) as Map<String, dynamic>;

  return SamplePage158Message.fromJson(json);
}

class SamplePage158Message {
  SamplePage158Message({
    required this.message,
  });

  factory SamplePage158Message.fromJson(Map<String, dynamic> json) =>
      SamplePage158Message(
        message: json['message'] as String,
      );

  final String message;
}

結果

動画

公式リファレンス

Isolates
Information on writing isolates in Dart.

#159 Tween

Tweenとは?

設定された開始値から終了値にスムーズに移行するのに役立つオブジェクトです。

とくにアニメーション利用時に使われることが多いです。

サンプルコード

Tweenを使ったサンプルはたくさんあるので割愛

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

結果

Tweenを使ったサンプルはたくさんあるので割愛

動画

公式リファレンス

Tween class - animation library - Dart API
API docs for the Tween class from the animation library, for the Dart programming language.

さいごに

再び追いついた!

おすすめ参考書

リンク

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

コメント

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