COMPANY SERVICE STAFF BLOG NEWS CONTACT

STAFF BLOG

スタッフブログ

TECHNICAL

テクログ

2023.02.03

Flutter3.7をさわってみた

テクログ

はじめに

お久しぶりです!
のりさんです

先日 Flutter Forward 2023 が開催されましたね。
Flutterが 3.7 になったようです。

また正式版はまだ先の話になりますが
Dart3α の紹介にあった Flutter for Webの WebAssembly が気になりました。

FlutterのWebアプリが JSからWASMになることで
ネイティブに近いパフォーマンスになることを期待しています。

さて今回は最新の Flutter3.7 の一部をさわってみたいと思います。

Material3対応ウィジェットの追加

バージョンアップによって多くのウィジェットがMaterial3に対応したようです。
以下のURLからサンプルプログラムが確認可能です。

【ソースコード】
 https://github.com/flutter/samples/tree/main/material_3_demo
【デモサイト】
 https://flutter.github.io/samples/web/material_3_demo/#/

多くのウィジェットが対応されたみたいですね!
詳細はこちらのサイトから確認できるようです。
https://github.com/flutter/flutter/issues/91605

メニュー関連ウィジェットの追加

Flutter3.7でメニュー関連のウィジェットが追加されたようです。
サンプルプログラムを修正して、少しさわってみたいと思います。

■ 画面

さくっとメニューが作れました。
ショートカットキーも割り当てられるので設定してみました。
(altキーを押すと下線が表示されました)

■ソースコード

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

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            const MenuSample(),
            Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Text('You have pushed the button this many times:'),
                  Text('$_counter', style: Theme.of(context).textTheme.headlineMedium),
                ]
            )),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

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

  void _showMessage(BuildContext context, String message) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
  }

  @override
  Widget build(BuildContext context) {

    ShortcutRegistry.of(context).addAll({
      SingleActivator(LogicalKeyboardKey.keyC, control: true) : VoidCallbackIntent( () { _showMessage(context, 'コピー'); }),
      SingleActivator(LogicalKeyboardKey.keyV, control: true) : VoidCallbackIntent( () { _showMessage(context, '貼り付け'); }),
    });

    return Column(children: <Widget>[
      Row(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Expanded(
            child: MenuBar(
              children: <Widget>[
                SubmenuButton(
                  menuChildren: <Widget>[
                    MenuItemButton(
                        leadingIcon: const Icon(Icons.add_outlined),
                        onPressed: () => _showMessage(context, '新規作成'),
                        child: const MenuAcceleratorLabel('新規(&N)'),
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.file_open_outlined),
                      onPressed: () => _showMessage(context, '開く'),
                      child: const MenuAcceleratorLabel('開く(&O)...'),
                    ),
                    const PopupMenuDivider(),
                    MenuItemButton(
                        leadingIcon: const Icon(Icons.save_outlined),
                        onPressed: () => _showMessage(context, '名前を付けて保存'),
                        child: const MenuAcceleratorLabel('名前を付けて保存(&A)...')
                    ),
                    const PopupMenuDivider(),
                    MenuItemButton(
                        leadingIcon: const Icon(Icons.exit_to_app_outlined),
                        onPressed: () => _showMessage(context, '終了'),
                        child: const MenuAcceleratorLabel('終了(&E)')
                    ),
                  ],
                  child: const MenuAcceleratorLabel('ファイル(&F)'),
                ),
                SubmenuButton(
                  menuChildren: <Widget>[
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.undo_outlined),
                      onPressed: () => _showMessage(context, '元に戻す'),
                      child: const MenuAcceleratorLabel('元に戻す(&U)'),
                    ),
                    const PopupMenuDivider(),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.copy_outlined),
                      onPressed: () => _showMessage(context, 'コピー'),
                      shortcut: const SingleActivator(LogicalKeyboardKey.keyC, control: true),
                      child: const MenuAcceleratorLabel('コピー'),
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.paste_outlined),
                      onPressed: () => _showMessage(context, '貼り付け'),
                      shortcut: const SingleActivator(LogicalKeyboardKey.keyV, control: true),
                      child: const MenuAcceleratorLabel('貼り付け'),
                    ),
                  ],
                  child: const MenuAcceleratorLabel('編集(&E)'),
                ),
              ],
            ),
          ),
        ],
      )
    ]);
  }
}

おわりに

今回はFlutter3.7の一部機能をさわってみました。
メニューについては、さくっと作れたのでオススメです!

それではまた!

この記事を書いた人

のりさん

入社年2014年

出身地東京都

業務内容開発

特技・趣味水泳・筋トレ・旅行

テクログに関する記事一覧

TOP