カテゴリー
学術

確率の哲学的試論

 ラプラスという人は単なる数学者ではなく激動のフランス革命を生き抜いた偉人だったのは知りませんでした。賭け事が好きな人にお勧めしたい一冊です。

カテゴリー
学術

真空マイクロエレクトロニクス

カテゴリー
学術

Flutterで状態管理あれこれ2

 状態管理の元となるInheritedWidgetを理解するためにカウンターアプリを改造して実装してみましたがとても複雑でした。

 それで流行りのパッケージを実装してみました。使いやすいように InheritedWidget をラップしているのでコードは短くなるのですが、バージョンによって細かく記述方法が異なりなり正解にたどり着くのが大変です。

  flutter_hooks: ^0.17.0
  hooks_riverpod: ^0.14.0+4
  state_notifier: ^0.7.0
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final viewModel = StateNotifierProvider((_) => ViewModel());

class ViewModel extends StateNotifier<int> {
  ViewModel() : super(0);
  void increment() => state++;
  void decrement() => state--;
}

void main() {
  runApp(
    ProviderScope(
      child: CounterApp(),
    ),
  );
}

class CounterApp extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _viewModel = useProvider(viewModel);

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('CounterApp')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                _viewModel.toString(),
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            FloatingActionButton(
              heroTag: 'increment',
              onPressed: () => context.read(viewModel.notifier).increment(),
              child: Icon(Icons.add),
            ),
            Gap(15),
            FloatingActionButton(
              heroTag: 'decrement',
              onPressed: () => context.read(viewModel.notifier).decrement(),
              child: Icon(Icons.remove_circle_outline),
            ),
          ],
        ),
      ),
    );
  }
}

 このコードもパッケージのバージョンがちょっとでも上がれば直さなくなると思います。

Flutterで状態管理あれこれ2
Flutterで状態管理あれこれ2

実機のスクリーンショットは
flutter screenshot
で撮れます。プロジェクトフォルダーに画像が保存される。

カテゴリー
学術

Flutterで角を丸くする

 TextFieldやDropdownButtonの角を丸くしてみた。結局ConainerのBorderを丸くして角が丸くなったように見せるだけだった。

Flutterで角を丸くする
Flutterで角を丸くする
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    String dropdownValue = 'One';
    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ClipRRect(
              borderRadius: BorderRadius.all(Radius.circular(30)),
              child: Container(
                width: 200,
                height: 100,
                color: Colors.yellow,
                child: Padding(
                  padding: const EdgeInsets.all(8),
                  child: const TextField(
                    obscureText: true,
                    decoration: InputDecoration(
                      border: InputBorder.none,
                      labelText: 'Pass',
                    ),
                  ),
                ),
              ),
            ),
            Gap(20),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 5),
              width: 200,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.blue),
                borderRadius: BorderRadius.circular(20),
              ),
              child: const TextField(
                obscureText: true,
                decoration: InputDecoration(
                  border: InputBorder.none,
                  labelText: 'Pass',
                ),
              ),
            ),
            Gap(20),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 5),
              width: 200,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.blue),
                borderRadius: BorderRadius.circular(20),
              ),
              child: DropdownButton<String>(
                value: dropdownValue,
                icon: const Icon(Icons.arrow_downward),
                iconSize: 24,
                elevation: 16,
                style: const TextStyle(color: Colors.deepPurple),
                onChanged: (String? newValue) {},
                items: <String>['One', 'Two', 'Free', 'Four']
                    .map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
              ),
            ),
            Gap(20),
            Text(
              'You have pushed the button this many times:',
              style: TextStyle(color: Colors.white),
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
カテゴリー
学術

Flutterの状態管理あれこれ

 状態管理の要点はその状態に影響を受けるWidgetのみが状態変化に対する処理を行えるように効率化することです。

InheritedWidget
 Flutter自身を構成するWidgetの一つ。Widgetツリーの配下に効率的に情報を伝える仕組みを提供します。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(
        key: null,
        child: Scaffold(
          appBar: AppBar(
            title: Text("Inherited Widget Sample"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                WidgetNumText(),
                WidgetCenterText(
                  key: null,
                ),
              ],
            ),
          ),
          floatingActionButton: WidgetIncrementBtn(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({required Key? key, required this.child}) : super(key: key);

  final Widget child;

  @override
  _MyHomePageState createState() => _MyHomePageState();

  static _MyHomePageState of(BuildContext context, {bool rebuild = true}) {
    return rebuild
        ? (context.dependOnInheritedWidgetOfExactType<_InheritedWidget>()
                as _InheritedWidget)
            .data
        : (context
                .getElementForInheritedWidgetOfExactType<_InheritedWidget>()!
                .widget as _InheritedWidget)
            .data;
  }
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return _InheritedWidget(
      child: widget.child,
      data: this,
    );
  }
}

class WidgetIncrementButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _MyHomePageState state = MyHomePage.of(context, rebuild: false);
    return FloatingActionButton(
      onPressed: () => state._incrementCounter(),
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }
}

class _InheritedWidget extends InheritedWidget {
  _InheritedWidget({
    Key? key,
    required Widget child,
    required this.data,
  }) : super(key: key, child: child);

  final _MyHomePageState data;

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;
}

class WidgetNumText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _MyHomePageState state = MyHomePage.of(context);
    return Text(
      '${state._counter}',
      style: Theme.of(context).textTheme.headline4,
    );
  }
}

class WidgetIncrementBtn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _MyHomePageState state = MyHomePage.of(context, rebuild: false);
    return FloatingActionButton(
      onPressed: () => state._incrementCounter(),
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }
}

class WidgetCenterText extends StatelessWidget {
  const WidgetCenterText({required Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Text('You have pushed the button this many times:');
  }
}

Memo
Shader compilation errorが出たら
エミュレーターからアプリを消してflutter cleanする


Provider
 InheritedWidgetのラッパークラスで状態管理とDI機能を提供します。

StateNotifer
状態管理パッケージでProviderをベースに作られている。同じ作者。

カテゴリー
学術

UbuntuでもFlutter開発環境を作ってみた

 Android Studioは公式の説明通りにインストールしFlutterとDartのプラグインを追加した。

Google Pixelを有効にするためのコマンド
echo "SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"18d1\", MODE=\"0666\", GROUP=\"plugdev\"" > /tmp/51-android.rules
sudo cp /tmp/51-android.rules /etc/udev/rules.d/51-android.rules

Flutterのインストール
git clone https://github.com/flutter/flutter
sudo mv flutter /usr/local/
sudo apt install clang curl pkg-config ninja-sudo apt install clang curl pkg-config ninja-build cmake libgtk-3-dev libblkid-dev liblzma-dev unzipbuild cmake libgtk-3-dev libblkid-dev liblzma-dev unzip
flutter config --enable-linux-desktop
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 2.5.0-7.0.pre.182, on Ubuntu 20.04.3 LTS
    5.4.0-83-generic, locale ja_JP.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2020.3)
[✓] Android Studio
[✓] VS Code (version 1.59.1)
[✓] Connected device (4 available)
Kindle Fire 7で Flutter
Kindle Fire 7で Flutter

更にKindle Fire 7 で実行してみた。

カテゴリー
学術

狭くてWindows PCの置き場が無くなった

裸PC

ワイヤーラックの棚の裏に園芸用のビニタイで裸のままぶら下げたら案外良かった。

カテゴリー
学術

Flutter Appをデバッグ実行したらflutter upgradeと表示された

ので素直にupgradeしてみた。

╔════════════════════════════════════════════════════════════════════════════╗
║ A new version of Flutter is available!                                     ║
║                                                                            ║
║ To update to the latest version, run "flutter upgrade".                    ║
╚════════════════════════════════════════════════════════════════════════════╝
developer@Mac-mini my_app_01 % flutter upgrade
Upgrading Flutter to 2.5.0-7.0.pre.80 from 2.4.0-5.0.pre.166 in /Users/developer/Documents/flutter...
Downloading Dart SDK from Flutter engine a447901bc58b277a986e665520c42ed1ad2cb945...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0  221M    0  1340    0     0   1956      0 32:58:21 --:--:-- 32:58:21  1953
  0  221M    0 1134k    0     0   733k      0  0:05:09  0:00:01  0:05:08  732k
  1  221M    1 2462k    0     0   964k      0  0:03:55  0:00:02  0:03:53  964k
  1  221M    1 3694k    0     0  1038k      0  0:03:38  0:00:03  0:03:35 1038k
  2  221M    2 4750k    0     0  1043k      0  0:03:37  0:00:04  0:03:33 1043k
  2  221M    2 5998k    0     0  1080k      0  0:03:29  0:00:05  0:03:24 1231k
  3  221M    3 7150k    0     0  1087k      0  0:03:28  0:00:06  0:03:22 1196k
  3  221M    3 8366k    0     0  1108k      0  0:03:24  0:00:07  0:03:17 1181k
  4  221M    4 9390k    0     0  1098k      0  0:03:26  0:00:08  0:03:18 1141k
  4  221M    4 10.4M    0     0  1117k      0  0:03:22  0:00:09  0:03:13 1184k
  5  221M    5 11.5M    0     0  1120k      0  0:03:22  0:00:10  0:03:12 1164k
  5  221M    5 12.7M    0     0  1125k      0  0:03:21  0:00:11  0:03:10 1175k
  6  221M    6 13.8M    0     0  1128k      0  0:03:20  0:00:12  0:03:08 1159k
  6  221M    6 14.9M    0     0  1131k      0  0:03:20  0:00:13  0:03:07 1187k
  7  221M    7 16.1M    0     0  1137k      0  0:03:19  0:00:14  0:03:05 1175k
  7  221M    7 17.3M    0     0  1138k      0  0:03:19  0:00:15  0:03:04 1177k
  8  221M    8 18.3M    0     0  1130k      0  0:03:20  0:00:16  0:03:04 1142k
  8  221M    8 19.3M    0     0  1130k      0  0:03:20  0:00:17  0:03:03 1134k
  9  221M    9 20.4M    0     0  1130k      0  0:03:20  0:00:18  0:03:02 1129k
  9  221M    9 21.3M    0     0  1116k      0  0:03:23  0:00:19  0:03:04 1056k
 10  221M   10 22.3M    0     0  1111k      0  0:03:23  0:00:20  0:03:03 1027k
 10  221M   10 23.2M    0     0  1103k      0  0:03:25  0:00:21  0:03:04 1009k
 11  221M   11 24.5M    0     0  1112k      0  0:03:23  0:00:22  0:03:01 1048k
 11  221M   11 25.6M    0     0  1114k      0  0:03:23  0:00:23  0:03:00 1054k
 12  221M   12 26.7M    0     0  1113k      0  0:03:23  0:00:24  0:02:59 1102k
 12  221M   12 27.7M    0     0  1113k      0  0:03:23  0:00:25  0:02:58 1119k
 12  221M   12 28.7M    0     0  1107k      0  0:03:24  0:00:26  0:02:58 1126k
 13  221M   13 29.6M    0     0  1101k      0  0:03:25  0:00:27  0:02:58 1055k
 13  221M   13 30.8M    0     0  1105k      0  0:03:25  0:00:28  0:02:57 1065k
 14  221M   14 32.0M    0     0  1109k      0  0:03:24  0:00:29  0:02:55 1088k
 14  221M   14 33.1M    0     0  1111k      0  0:03:23  0:00:30  0:02:53 1105k
 15  221M   15 34.2M    0     0  1113k      0  0:03:23  0:00:31  0:02:52 1142k
 16  221M   16 35.4M    0     0  1114k      0  0:03:23  0:00:32  0:02:51 1186k
 16  221M   16 36.4M    0     0  1111k      0  0:03:24  0:00:33  0:02:51 1141k
 16  221M   16 37.1M    0     0  1100k      0  0:03:25  0:00:34  0:02:51 1049k
 16  221M   16 37.3M    0     0  1076k      0  0:03:30  0:00:35  0:02:55  857k
 16  221M   16 37.5M    0     0  1051k      0  0:03:35  0:00:36  0:02:59  662k
 17  221M   17 38.5M    0     0  1050k      0  0:03:35  0:00:37  0:02:58  631k
 17  221M   17 39.6M    0     0  1052k      0  0:03:35  0:00:38  0:02:57  659k
 18  221M   18 40.7M    0     0  1055k      0  0:03:34  0:00:39  0:02:55  739k
 18  221M   18 41.7M    0     0  1053k      0  0:03:35  0:00:40  0:02:55  897k
 19  221M   19 42.6M    0     0  1050k      0  0:03:35  0:00:41  0:02:54 1046k
 19  221M   19 43.7M    0     0  1052k      0  0:03:35  0:00:42  0:02:53 1066k
 20  221M   20 44.9M    0     0  1055k      0  0:03:34  0:00:43  0:02:51 1078k
 20  221M   20 45.8M    0     0  1053k      0  0:03:35  0:00:44  0:02:51 1044k
 21  221M   21 47.1M    0     0  1060k      0  0:03:33  0:00:45  0:02:48 1110k
 21  221M   21 48.1M    0     0  1059k      0  0:03:34  0:00:46  0:02:48 1129k
 22  221M   22 49.2M    0     0  1060k      0  0:03:33  0:00:47  0:02:46 1133k
 22  221M   22 50.5M    0     0  1065k      0  0:03:32  0:00:48  0:02:44 1152k
 23  221M   23 51.6M    0     0  1066k      0  0:03:32  0:00:49  0:02:43 1183k
 23  221M   23 52.7M    0     0  1068k      0  0:03:32  0:00:50  0:02:42 1141k
 24  221M   24 53.6M    0     0  1065k      0  0:03:32  0:00:51  0:02:41 1119k
 24  221M   24 54.6M    0     0  1065k      0  0:03:32  0:00:52  0:02:40 1108k
 24  221M   24 54.8M    0     0  1049k      0  0:03:36  0:00:53  0:02:43  891k
 24  221M   24 55.1M    0     0  1034k      0  0:03:39  0:00:54  0:02:45  713k
 25  221M   25 56.1M    0     0  1034k      0  0:03:39  0:00:55  0:02:44  693k
 25  221M   25 57.0M    0     0  1033k      0  0:03:39  0:00:56  0:02:43  707k
 26  221M   26 58.2M    0     0  1035k      0  0:03:38  0:00:57  0:02:41  726k
 26  221M   26 59.3M    0     0  1038k      0  0:03:38  0:00:58  0:02:40  922k
 27  221M   27 60.4M    0     0  1038k      0  0:03:38  0:00:59  0:02:39 1080k
 27  221M   27 61.2M    0     0  1036k      0  0:03:38  0:01:00  0:02:38 1057k
 28  221M   28 62.4M    0     0  1038k      0  0:03:38  0:01:01  0:02:37 1094k
 28  221M   28 63.6M    0     0  1041k      0  0:03:37  0:01:02  0:02:35 1100k
 29  221M   29 64.7M    0     0  1042k      0  0:03:37  0:01:03  0:02:34 1095k
 29  221M   29 65.8M    0     0  1045k      0  0:03:36  0:01:04  0:02:32 1124k
 30  221M   30 67.0M    0     0  1046k      0  0:03:36  0:01:05  0:02:31 1175k
 30  221M   30 68.0M    0     0  1047k      0  0:03:36  0:01:06  0:02:30 1159k
 31  221M   31 69.1M    0     0  1047k      0  0:03:36  0:01:07  0:02:29 1121k
 31  221M   31 70.2M    0     0  1048k      0  0:03:36  0:01:08  0:02:28 1122k
 32  221M   32 71.3M    0     0  1049k      0  0:03:35  0:01:09  0:02:26 1110k
 32  221M   32 72.3M    0     0  1050k      0  0:03:35  0:01:10  0:02:25 1096k
 33  221M   33 73.4M    0     0  1051k      0  0:03:35  0:01:11  0:02:24 1104k
 33  221M   33 74.6M    0     0  1053k      0  0:03:35  0:01:12  0:02:23 1134k
 34  221M   34 75.7M    0     0  1054k      0  0:03:35  0:01:13  0:02:22 1134k
 34  221M   34 76.8M    0     0  1054k      0  0:03:35  0:01:14  0:02:21 1121k
 35  221M   35 77.8M    0     0  1054k      0  0:03:35  0:01:15  0:02:20 1110k
 35  221M   35 78.9M    0     0  1056k      0  0:03:34  0:01:16  0:02:18 1123k
 36  221M   36 80.0M    0     0  1056k      0  0:03:34  0:01:17  0:02:17 1107k
 36  221M   36 81.0M    0     0  1056k      0  0:03:34  0:01:18  0:02:16 1081k
 36  221M   36 81.9M    0     0  1054k      0  0:03:35  0:01:19  0:02:16 1052k
 37  221M   37 82.8M    0     0  1053k      0  0:03:35  0:01:20  0:02:15 1043k
 38  221M   38 84.2M    0     0  1057k      0  0:03:34  0:01:21  0:02:13 1070k
 38  221M   38 85.2M    0     0  1057k      0  0:03:34  0:01:22  0:02:12 1074k
 38  221M   38 86.3M    0     0  1058k      0  0:03:34  0:01:23  0:02:11 1088k
 39  221M   39 87.2M    0     0  1056k      0  0:03:34  0:01:24  0:02:10 1083k
 39  221M   39 87.4M    0     0  1046k      0  0:03:36  0:01:25  0:02:11  926k
 39  221M   39 87.6M    0     0  1037k      0  0:03:38  0:01:26  0:02:12  713k
 40  221M   40 88.9M    0     0  1039k      0  0:03:38  0:01:27  0:02:11  742k
 40  221M   40 90.0M    0     0  1041k      0  0:03:37  0:01:28  0:02:09  761k
 41  221M   41 91.2M    0     0  1043k      0  0:03:37  0:01:29  0:02:08  822k
 41  221M   41 92.0M    0     0  1041k      0  0:03:37  0:01:30  0:02:07  952k
 41  221M   41 92.7M    0     0  1037k      0  0:03:38  0:01:31  0:02:07 1038k
 42  221M   42 93.7M    0     0  1036k      0  0:03:38  0:01:32  0:02:06  983k
 42  221M   42 94.5M    0     0  1035k      0  0:03:39  0:01:33  0:02:06  921k
 43  221M   43 95.6M    0     0  1035k      0  0:03:38  0:01:34  0:02:04  897k
 43  221M   43 96.5M    0     0  1035k      0  0:03:39  0:01:35  0:02:04  924k
 44  221M   44 97.7M    0     0  1036k      0  0:03:38  0:01:36  0:02:02 1015k
 44  221M   44 98.8M    0     0  1037k      0  0:03:38  0:01:37  0:02:01 1057k
 45  221M   45  100M    0     0  1039k      0  0:03:38  0:01:38  0:02:00 1116k
 45  221M   45  101M    0     0  1040k      0  0:03:37  0:01:39  0:01:58 1131k
 46  221M   46  102M    0     0  1039k      0  0:03:38  0:01:40  0:01:58 1123k
 46  221M   46  103M    0     0  1039k      0  0:03:38  0:01:41  0:01:57 1099k
 47  221M   47  104M    0     0  1040k      0  0:03:37  0:01:42  0:01:55 1097k
 47  221M   47  105M    0     0  1039k      0  0:03:38  0:01:43  0:01:55 1046k
 47  221M   47  106M    0     0  1038k      0  0:03:38  0:01:44  0:01:54 1008k
 48  221M   48  107M    0     0  1039k      0  0:03:38  0:01:45  0:01:53 1050k
 48  221M   48  108M    0     0  1042k      0  0:03:37  0:01:46  0:01:51 1095k
 49  221M   49  109M    0     0  1043k      0  0:03:37  0:01:47  0:01:50 1090k
 49  221M   49  110M    0     0  1043k      0  0:03:37  0:01:48  0:01:49 1128k
 50  221M   50  111M    0     0  1043k      0  0:03:37  0:01:49  0:01:48 1136k
 50  221M   50  112M    0     0  1041k      0  0:03:37  0:01:50  0:01:47 1074k
 51  221M   51  113M    0     0  1041k      0  0:03:37  0:01:51  0:01:46 1033k
 51  221M   51  114M    0     0  1042k      0  0:03:37  0:01:52  0:01:45 1026k
 52  221M   52  115M    0     0  1041k      0  0:03:37  0:01:53  0:01:44  992k
 52  221M   52  116M    0     0  1040k      0  0:03:37  0:01:54  0:01:43  984k
 53  221M   53  117M    0     0  1042k      0  0:03:37  0:01:55  0:01:42 1069k
 53  221M   53  118M    0     0  1043k      0  0:03:37  0:01:56  0:01:41 1089k
 54  221M   54  119M    0     0  1043k      0  0:03:37  0:01:57  0:01:40 1080k
 54  221M   54  121M    0     0  1045k      0  0:03:36  0:01:58  0:01:38 1133k
 55  221M   55  122M    0     0  1046k      0  0:03:36  0:01:59  0:01:37 1176k
 55  221M   55  123M    0     0  1047k      0  0:03:36  0:02:00  0:01:36 1152k
 56  221M   56  124M    0     0  1048k      0  0:03:36  0:02:01  0:01:35 1154k
 56  221M   56  125M    0     0  1048k      0  0:03:36  0:02:02  0:01:34 1164k
 57  221M   57  126M    0     0  1049k      0  0:03:36  0:02:03  0:01:33 1138k
 57  221M   57  127M    0     0  1051k      0  0:03:35  0:02:04  0:01:31 1168k
 58  221M   58  128M    0     0  1051k      0  0:03:35  0:02:05  0:01:30 1155k
 58  221M   58  130M    0     0  1052k      0  0:03:35  0:02:06  0:01:29 1167k
 59  221M   59  131M    0     0  1053k      0  0:03:35  0:02:07  0:01:28 1181k
 59  221M   59  132M    0     0  1053k      0  0:03:35  0:02:08  0:01:27 1158k
 60  221M   60  132M    0     0  1051k      0  0:03:35  0:02:09  0:01:26 1053k
 60  221M   60  133M    0     0  1050k      0  0:03:35  0:02:10  0:01:25 1018k
 60  221M   60  134M    0     0  1049k      0  0:03:35  0:02:11  0:01:24  973k
 61  221M   61  136M    0     0  1050k      0  0:03:35  0:02:12  0:01:23  957k
 61  221M   61  137M    0     0  1051k      0  0:03:35  0:02:13  0:01:22 1007k
 62  221M   62  138M    0     0  1052k      0  0:03:35  0:02:14  0:01:21 1084k
 62  221M   62  139M    0     0  1053k      0  0:03:35  0:02:15  0:01:20 1135k
 63  221M   63  140M    0     0  1054k      0  0:03:35  0:02:16  0:01:19 1167k
 63  221M   63  141M    0     0  1054k      0  0:03:35  0:02:17  0:01:18 1168k
 64  221M   64  142M    0     0  1055k      0  0:03:34  0:02:18  0:01:16 1159k
 64  221M   64  143M    0     0  1054k      0  0:03:35  0:02:19  0:01:16 1108k
 65  221M   65  144M    0     0  1055k      0  0:03:34  0:02:20  0:01:14 1120k
 65  221M   65  145M    0     0  1054k      0  0:03:34  0:02:21  0:01:13 1068k
 66  221M   66  146M    0     0  1054k      0  0:03:35  0:02:22  0:01:13 1051k
 66  221M   66  147M    0     0  1054k      0  0:03:34  0:02:23  0:01:11 1038k
 67  221M   67  148M    0     0  1054k      0  0:03:34  0:02:24  0:01:10 1057k
 67  221M   67  149M    0     0  1053k      0  0:03:35  0:02:25  0:01:10 1001k
 68  221M   68  151M    0     0  1055k      0  0:03:34  0:02:26  0:01:08 1079k
 68  221M   68  151M    0     0  1054k      0  0:03:35  0:02:27  0:01:08 1052k
 69  221M   69  152M    0     0  1054k      0  0:03:34  0:02:28  0:01:06 1045k
 69  221M   69  154M    0     0  1055k      0  0:03:34  0:02:29  0:01:05 1066k
 70  221M   70  155M    0     0  1056k      0  0:03:34  0:02:30  0:01:04 1138k
 70  221M   70  156M    0     0  1057k      0  0:03:34  0:02:31  0:01:03 1111k
 71  221M   71  157M    0     0  1057k      0  0:03:34  0:02:32  0:01:02 1158k
 71  221M   71  158M    0     0  1058k      0  0:03:34  0:02:33  0:01:01 1170k
 72  221M   72  159M    0     0  1058k      0  0:03:34  0:02:34  0:01:00 1164k
 72  221M   72  160M    0     0  1059k      0  0:03:34  0:02:35  0:00:59 1135k
 73  221M   73  162M    0     0  1060k      0  0:03:33  0:02:36  0:00:57 1153k
 73  221M   73  163M    0     0  1060k      0  0:03:33  0:02:37  0:00:56 1145k
 74  221M   74  164M    0     0  1060k      0  0:03:33  0:02:38  0:00:55 1122k
 74  221M   74  165M    0     0  1059k      0  0:03:33  0:02:39  0:00:54 1099k
 75  221M   75  166M    0     0  1059k      0  0:03:33  0:02:40  0:00:53 1081k
 75  221M   75  167M    0     0  1059k      0  0:03:34  0:02:41  0:00:53 1025k
 75  221M   75  168M    0     0  1059k      0  0:03:34  0:02:42  0:00:52 1027k
 76  221M   76  169M    0     0  1060k      0  0:03:33  0:02:43  0:00:50 1070k
 77  221M   77  170M    0     0  1061k      0  0:03:33  0:02:44  0:00:49 1105k
 77  221M   77  171M    0     0  1062k      0  0:03:33  0:02:45  0:00:48 1128k
 78  221M   78  172M    0     0  1062k      0  0:03:33  0:02:46  0:00:47 1158k
 78  221M   78  173M    0     0  1061k      0  0:03:33  0:02:47  0:00:46 1128k
 78  221M   78  174M    0     0  1061k      0  0:03:33  0:02:48  0:00:45 1077k
 79  221M   79  175M    0     0  1060k      0  0:03:33  0:02:49  0:00:44 1047k
 79  221M   79  176M    0     0  1061k      0  0:03:33  0:02:50  0:00:43 1027k
 80  221M   80  177M    0     0  1059k      0  0:03:33  0:02:51  0:00:42  967k
 80  221M   80  177M    0     0  1055k      0  0:03:34  0:02:52  0:00:42  837k
 80  221M   80  178M    0     0  1050k      0  0:03:35  0:02:53  0:00:42  682k
 80  221M   80  179M    0     0  1051k      0  0:03:35  0:02:54  0:00:41  724k
 81  221M   81  180M    0     0  1051k      0  0:03:35  0:02:55  0:00:40  725k
 81  221M   81  181M    0     0  1051k      0  0:03:35  0:02:56  0:00:39  786k
 82  221M   82  182M    0     0  1052k      0  0:03:35  0:02:57  0:00:38  967k
 82  221M   82  183M    0     0  1053k      0  0:03:35  0:02:58  0:00:37 1161k
 83  221M   83  184M    0     0  1052k      0  0:03:35  0:02:59  0:00:36 1114k
 83  221M   83  185M    0     0  1054k      0  0:03:34  0:03:00  0:00:34 1166k
 84  221M   84  187M    0     0  1055k      0  0:03:34  0:03:01  0:00:33 1170k
 85  221M   85  188M    0     0  1055k      0  0:03:34  0:03:02  0:00:32 1170k
 85  221M   85  189M    0     0  1056k      0  0:03:34  0:03:03  0:00:31 1161k
 85  221M   85  190M    0     0  1056k      0  0:03:34  0:03:04  0:00:30 1187k
 86  221M   86  191M    0     0  1056k      0  0:03:34  0:03:05  0:00:29 1122k
 86  221M   86  192M    0     0  1056k      0  0:03:34  0:03:06  0:00:28 1121k
 87  221M   87  193M    0     0  1056k      0  0:03:34  0:03:07  0:00:27 1081k
 87  221M   87  194M    0     0  1056k      0  0:03:34  0:03:08  0:00:26 1061k
 88  221M   88  195M    0     0  1056k      0  0:03:34  0:03:09  0:00:25 1060k
 88  221M   88  196M    0     0  1056k      0  0:03:34  0:03:10  0:00:24 1061k
 89  221M   89  197M    0     0  1056k      0  0:03:34  0:03:11  0:00:23 1056k
 89  221M   89  198M    0     0  1057k      0  0:03:34  0:03:12  0:00:22 1093k
 90  221M   90  199M    0     0  1057k      0  0:03:34  0:03:13  0:00:21 1111k
 90  221M   90  201M    0     0  1058k      0  0:03:34  0:03:14  0:00:20 1125k
 91  221M   91  202M    0     0  1059k      0  0:03:34  0:03:15  0:00:19 1151k
 91  221M   91  203M    0     0  1058k      0  0:03:34  0:03:16  0:00:18 1138k
 92  221M   92  204M    0     0  1059k      0  0:03:34  0:03:17  0:00:17 1126k
 92  221M   92  205M    0     0  1059k      0  0:03:33  0:03:18  0:00:15 1122k
 93  221M   93  206M    0     0  1060k      0  0:03:33  0:03:19  0:00:14 1128k
 93  221M   93  207M    0     0  1060k      0  0:03:33  0:03:20  0:00:13 1132k
 94  221M   94  208M    0     0  1061k      0  0:03:33  0:03:21  0:00:12 1159k
 94  221M   94  210M    0     0  1062k      0  0:03:33  0:03:22  0:00:11 1172k
 95  221M   95  211M    0     0  1062k      0  0:03:33  0:03:23  0:00:10 1174k
 95  221M   95  212M    0     0  1062k      0  0:03:33  0:03:24  0:00:09 1171k
 96  221M   96  213M    0     0  1063k      0  0:03:33  0:03:25  0:00:08 1169k
 96  221M   96  214M    0     0  1063k      0  0:03:33  0:03:26  0:00:07 1154k
 97  221M   97  215M    0     0  1064k      0  0:03:33  0:03:27  0:00:06 1148k
 97  221M   97  216M    0     0  1064k      0  0:03:33  0:03:28  0:00:05 1142k
 98  221M   98  217M    0     0  1065k      0  0:03:32  0:03:29  0:00:03 1154k
 98  221M   98  218M    0     0  1065k      0  0:03:32  0:03:30  0:00:02 1131k
 98  221M   98  219M    0     0  1061k      0  0:03:33  0:03:31  0:00:02  954k
 99  221M   99  219M    0     0  1056k      0  0:03:34  0:03:32  0:00:02  751k
 99  221M   99  220M    0     0  1055k      0  0:03:34  0:03:33  0:00:01  682k
 99  221M   99  221M    0     0  1056k      0  0:03:34  0:03:34 --:--:--  702k
100  221M  100  221M    0     0  1056k      0  0:03:34  0:03:34 --:--:--  616k
Building flutter tool...

Upgrading engine...
Downloading android-arm-profile/darwin-x64 tools...                 3.2s
Downloading android-arm-release/darwin-x64 tools...              2,600ms
Downloading android-arm64-profile/darwin-x64 tools...               3.4s
Downloading android-arm64-release/darwin-x64 tools...            2,644ms
Downloading android-x64-profile/darwin-x64 tools...              2,881ms
Downloading android-x64-release/darwin-x64 tools...              2,609ms
Downloading android-x86 tools...                                   25.7s
Downloading android-x64 tools...                                   21.5s
Downloading android-arm tools...                                   10.1s
Downloading android-arm-profile tools...                            5.2s
Downloading android-arm-release tools...                            4.4s
Downloading android-arm64 tools...                                 10.9s
Downloading android-arm64-profile tools...                          6.0s
Downloading android-arm64-release tools...                          4.6s
Downloading android-x64-profile tools...                            6.6s
Downloading android-x64-release tools...                            4.7s
Downloading android-x86-jit-release tools...                        7.3s
Downloading ios tools...                                           48.6s
Downloading ios-profile tools...                                   39.4s
Downloading ios-release tools...                                  188.4s
Downloading Web SDK...                                             32.5s
Downloading package sky_engine...                                1,729ms
Downloading flutter_patched_sdk tools...                            4.1s
Downloading flutter_patched_sdk_product tools...                    3.5s
Downloading darwin-x64 tools...                                    28.6s
Downloading darwin-x64/font-subset tools...                      1,248ms

Flutter 2.5.0-7.0.pre.80 • channel master • https://github.com/flutter/flutter.git
Framework • revision 1422bfa723 (71 minutes ago) • 2021-08-14 04:02:06 -0400
Engine • revision a447901bc5
Tools • Dart 2.15.0 (build 2.15.0-15.0.dev)

Running flutter doctor...
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 2.5.0-7.0.pre.80, on macOS 11.5.1 20G80 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] VS Code (version 1.59.0)
[✓] Connected device (3 available)

• No issues found!
developer@Mac-mini my_app_01 % 

無事にNo issues found!と出た。良かった。

カテゴリー
学術

Flutter AppにDropdownButtonを追加してみた

Flutter AppにDropdownButtonを追加してみた
Flutter AppにDropdownButtonを追加してみた
Flutter AppにDropdownButtonを追加してみた

lib/my_first_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

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

  @override
  State<MyFirstPage> createState() => _MyFirstPageState();
}

class _MyFirstPageState extends State<MyFirstPage> {
  late TextEditingController _controller;
  bool isChecked = false;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController();
  }

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

  @override
  Widget build(BuildContext context) {
    Color getColor(Set<MaterialState> states) {
      const Set<MaterialState> interactiveStates = <MaterialState>{
        MaterialState.pressed,
        MaterialState.hovered,
        MaterialState.focused,
      };
      if (states.any(interactiveStates.contains)) {
        return Colors.blue;
      }
      return Colors.red;
    }

    String dropdownValue = 'One';

    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.firstPage),
      ),
      body: Container(
        padding: const EdgeInsets.all(8),
        child: Column(
          children: <Widget>[
            Text(AppLocalizations.of(context)!.firstPage),
            TextField(
              controller: _controller,
              onSubmitted: (String value) async {
                await showDialog<void>(
                  context: context,
                  builder: (BuildContext context) {
                    return AlertDialog(
                      title: const Text('Title'),
                      content: Text(
                          '"$value", which has length ${value.characters.length}.'),
                      actions: <Widget>[
                        TextButton(
                          onPressed: () {
                            Navigator.pop(context);
                          },
                          child: const Text('OK'),
                        ),
                      ],
                    );
                  },
                );
              },
            ),
            Checkbox(
                checkColor: Colors.white,
                fillColor: MaterialStateProperty.resolveWith(getColor),
                value: isChecked,
                onChanged: (bool? value) {
                  setState(() {
                    isChecked = value!;
                  });
                }),
            DropdownButton<String>(
              value: dropdownValue,
              icon: const Icon(Icons.arrow_downward),
              iconSize: 24,
              elevation: 16,
              style: const TextStyle(color: Colors.deepPurple),
              underline: Container(
                height: 2,
                color: Colors.deepPurpleAccent,
              ),
              onChanged: (String? newValue) {
                setState(() {
                  dropdownValue = newValue!;
                });
              },
              items: <String>['One', 'Two', 'Free', 'Four']
                  .map<DropdownMenuItem<String>>((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value),
                );
              }).toList(),
            ),
          ],
        ),
      ),
    );
  }
}
カテゴリー
学術

Flutter AppにCheckboxを追加してみた

Flutter AppにCheckboxを追加してみた
Flutter AppにCheckboxを追加してみた

lib/my_first_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

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

  @override
  State<MyFirstPage> createState() => _MyFirstPageState();
}

class _MyFirstPageState extends State<MyFirstPage> {
  late TextEditingController _controller;
  bool isChecked = false;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController();
  }

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

  @override
  Widget build(BuildContext context) {
    Color getColor(Set<MaterialState> states) {
      const Set<MaterialState> interactiveStates = <MaterialState>{
        MaterialState.pressed,
        MaterialState.hovered,
        MaterialState.focused,
      };
      if (states.any(interactiveStates.contains)) {
        return Colors.blue;
      }
      return Colors.red;
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.firstPage),
      ),
      body: Container(
        padding: const EdgeInsets.all(8),
        child: Column(
          children: <Widget>[
            Text(AppLocalizations.of(context)!.firstPage),
            TextField(
              controller: _controller,
              onSubmitted: (String value) async {
                await showDialog<void>(
                  context: context,
                  builder: (BuildContext context) {
                    return AlertDialog(
                      title: const Text('Title'),
                      content: Text(
                          '"$value", which has length ${value.characters.length}.'),
                      actions: <Widget>[
                        TextButton(
                          onPressed: () {
                            Navigator.pop(context);
                          },
                          child: const Text('OK'),
                        ),
                      ],
                    );
                  },
                );
              },
            ),
            Checkbox(
                checkColor: Colors.white,
                fillColor: MaterialStateProperty.resolveWith(getColor),
                value: isChecked,
                onChanged: (bool? value) {
                  setState(() {
                    isChecked = value!;
                  });
                }),
          ],
        ),
      ),
    );
  }
}
カテゴリー
学術

Flutter AppにTextFieldを追加してみた

Flutter AppにTextFieldを追加してみた
Flutter AppにTextFieldを追加してみた

lib/my_app.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:my_app_01/my_first_page.dart';
import 'package:my_app_01/my_home_page.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: [
                Tab(icon: Icon(Icons.looks_one)),
                Tab(icon: Icon(Icons.looks_two)),
                Tab(icon: Icon(Icons.looks_3)),
              ],
            ),
            title: const Text('Tabs Demo'),
          ),
          body: const TabBarView(
            children: [
              MyFirstPage(),
              Icon(Icons.looks_two),
              MyHomePage(title: 'Flutter Demo Home Page'),
            ],
          ),
        ),
      ),
    );
  }
}

lib/my_first_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

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

  @override
  State<MyFirstPage> createState() => _MyFirstPageState();
}

class _MyFirstPageState extends State<MyFirstPage> {
  late TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.firstPage),
      ),
      body: Container(
        padding: const EdgeInsets.all(8),
        child: Column(
          children: <Widget>[
            const Text('First Page'),
            TextField(
              controller: _controller,
              onSubmitted: (String value) async {
                await showDialog<void>(
                  context: context,
                  builder: (BuildContext context) {
                    return AlertDialog(
                      title: const Text('Title'),
                      content: Text(
                          '"$value", which has length ${value.characters.length}.'),
                      actions: <Widget>[
                        TextButton(
                          onPressed: () {
                            Navigator.pop(context);
                          },
                          child: const Text('OK'),
                        ),
                      ],
                    );
                  },
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

lib/l10n/app_en.arb

{
    "helloWorld": "Hello World!",
    "@helloWorld": {
      "description": "The conventional newborn programmer greeting"
    },
    "firstPage": "First Page","@firstPage": {"description": "First Page Title"}
}

lib/l10n/app_ja.arb

{
    "helloWorld": "こんにちは。",
    "firstPage": "最初のページ"
}
カテゴリー
学術

Flutter AppにBottomNavigationBarを追加してみた

 アプリでよくある画面の下の方にタブバーを追加してみました。サンプルのまま追加しました。

Flutter AppにBottomNavigationBarを追加してみた
Flutter AppにBottomNavigationBarを追加してみた

lib/my_home_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Index 0: Home',
      style: optionStyle,
    ),
    Text(
      'Index 1: Business',
      style: optionStyle,
    ),
    Text(
      'Index 2: School',
      style: optionStyle,
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  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.center,
          children: <Widget>[
            Text(AppLocalizations.of(context)!.helloWorld),
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: 'Business',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'School',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}
カテゴリー
学術

Flutter AppにTabbarを追加する

 タブで画面を切り替えられるようにTabbarを追加してみます。画面の上側に表示されるTabbarです。

Flutter AppにTabbarを追加
Flutter AppにTabbarを追加

lib/my_app.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:my_app_01/my_home_page.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: [
                Tab(icon: Icon(Icons.looks_one)),
                Tab(icon: Icon(Icons.looks_two)),
                Tab(icon: Icon(Icons.looks_3)),
              ],
            ),
            title: const Text('Tabs Demo'),
          ),
          body: const TabBarView(
            children: [
              Icon(Icons.looks_one),
              Icon(Icons.looks_two),
              MyHomePage(title: 'Flutter Demo Home Page'),
            ],
          ),
        ),
      ),
    );
  }
}

 GoogleのMaterial Iconsは凄いですね。ダウンロードしてビルドプロジェクトにアイコン画像を登録しなくても、いきなりコード内で使用できます。アプリで使用するアイコンが全てMaterial Iconsだったら開発効率が良くなります。

カテゴリー
学術

Flutter Appの多言語化

 アプリの開発途中から多言語化対応するとあちこち修正しなければならなくなるので最初から多言語化前提で開発を行います。日本語のみであったとしてもアプリとしては多言語化対応しているけれども日本語のみ設定されている状態が望ましいです。

端末の言語設定を英語にする
端末の言語設定を英語にする
画面のテキストが英語になる
画面のテキストが英語になる
端末の言語設定を日本語にする
端末の言語設定を日本語にする
画面のテキストが日本語になる
画面のテキストが日本語になる

l10n.yaml

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0
#  intl_translation: 0.17.10+1

 intl_translation: 0.17.10+1はintl: ^0.17.0と合わないのでインストールできませんでした。

なので

return MaterialApp(
  onGenerateTitle: (BuildContext context) =>
      DemoLocalizations.of(context).title,

以降はできません。

lib/my_app.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:my_app_01/my_home_page.dart';

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

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

lib/my_home_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  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.center,
          children: <Widget>[
            Text(AppLocalizations.of(context)!.helloWorld),
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

lib/l10n/app_en.arb

{
    "helloWorld": "Hello World!",
    "@helloWorld": {
      "description": "The conventional newborn programmer greeting"
    }
}

lib/l10n/app_ja.arb

{
    "helloWorld": "こんにちは。"
}
カテゴリー
学術

Defaultアプリのdartファイルをクラス毎に分割する

 実際のアプリを開発するときは、起動時の処理、アプリの初期、トップ画面は別のクラスにしそのソースファイルは分割されているのでDefaultのアプリもそのように分割してみます。

main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  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.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

分割後

main.dart

import 'package:flutter/material.dart';
import 'package:my_app_01/my_app.dart';

void main() {
  runApp(const MyApp());
}

my_app.dart

import 'package:flutter/material.dart';
import 'package:my_app_01/my_home_page.dart';

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

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

my_home_page.dart

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  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.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
カテゴリー
学術

Repositoryが無くてもgit init

 ローカルだけで作業をするにしても履歴が確認できるのでプロジェクトのディレクトリでgit initとしておくと便利です。MACは標準でgitコマンドが使えます。

初めてgitを使うとき

git config --global user.email "mail@xxxxx.co.jp"
git config --global user.name "Name"

プロジェクトのディレクトリーに移動して

git init
git branch -m main
git commit --allow-empty -m "first commit"
カテゴリー
学術

Flutter Default Application

 Android StudioでFlutter Projectを新規作成するとデフォルトのアプリケーションが作成されます。

Android Studio Flutter Default Application
Android Studio Flutter Default Application
Flutter Default Application for iOS
Flutter Default Application for iOS

iOSや

Flutter Default Application for Android
Flutter Default Application for Android

Androidの実機でデバック実行しFlutterでアプリを開発する環境ができているか確認します。

カテゴリー
学術

Flutterのインストールで行った環境作り

.zshrc

export PATH=$PATH:/Applications/Android\ Studio.app/Contents/jre/Contents/Home/bin
export PATH=$PATH:/Users/developer/Documents/flutter/bin
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/Contents/Home
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

各環境

developer@Mac-mini my_app_01 % gem -v     
3.2.22

developer@Mac-mini my_app_01 % ruby --version
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]

developer@Mac-mini my_app_01 % rbenv versions                                   
  system
* 3.0.2 (set by /Users/developer/.rbenv/version)

developer@Mac-mini my_app_01 % brew -v
Homebrew 3.2.6
Homebrew/homebrew-core (git revision f909c2126a; last commit 2021-08-08)
Homebrew/homebrew-cask (git revision b4da68444e; last commit 2021-08-08)

developer@Mac-mini my_app_01 % xcode-select --version                         
xcode-select version 2384.

developer@Mac-mini my_app_01 % gem list ffi

*** LOCAL GEMS ***

ffi (1.15.3)
public_suffix (4.0.6)

developer@Mac-mini my_app_01 % xcodebuild -version
Xcode 13.0
Build version 13A5201i

developer@Mac-mini my_app_01 % pod --version
1.10.2

カテゴリー
学術

Flutter DoctorでUnable to find bundled Java version.

developer@Mac-mini ~ % flutter doctor -v
[✓] Flutter (Channel master, 2.4.0-5.0.pre.166, on macOS 11.5.1 20G80
    darwin-x64, locale ja-JP)
    • Flutter version 2.4.0-5.0.pre.166 at /Users/developer/Documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2dc11a85ff (2 weeks ago), 2021-07-22 17:56:03 -0700
    • Engine revision fbbb3b3f7b
    • Dart version 2.14.0 (build 2.14.0-343.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/developer/Library/Android/sdk
    • Platform android-30, build-tools 30.0.3
    • Java binary at: /Applications/Android Studio 4.2
      Preview.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 13.0, Build version 13A5201i
    • CocoaPods version 1.10.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio
    • Android Studio at /Applications/Android Studio 4.2 Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174)

[!] Android Studio (version 2020.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] VS Code (version 1.59.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.25.0

[✓] Connected device (2 available)
    • iPhone (mobile) • XXXXXXXX-XXXXXXXXXXXXXXXX • ios            • iOS 14.7.1
      18G82
    • Chrome (web)    • chrome                    • web-javascript • Google
      Chrome 92.0.4515.131
    ! Error: iPhone is busy: Fetching debug symbols for iPhone. Xcode will
      continue when iPhone is finished. (code -10)

! Doctor found issues in 1 category.

Unable to find bundled Java version.

が消えない。

developer@Mac-mini ~ % cd /Applications/Android\ Studio.app/Contents/jre
developer@Mac-mini jre % ln -s ../jre jdk
developer@Mac-mini jre % ln -s "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin" jdk

とすると解消した。

developer@Mac-mini my_app_01 % flutter doctor -v
[✓] Flutter (Channel master, 2.4.0-5.0.pre.166, on macOS 11.5.1 20G80
    darwin-x64, locale ja-JP)
    • Flutter version 2.4.0-5.0.pre.166 at /Users/developer/Documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2dc11a85ff (2 weeks ago), 2021-07-22 17:56:03 -0700
    • Engine revision fbbb3b3f7b
    • Dart version 2.14.0 (build 2.14.0-343.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/developer/Library/Android/sdk
    • Platform android-30, build-tools 30.0.3
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 13.0, Build version 13A5201i
    • CocoaPods version 1.10.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio
    • Android Studio at /Applications/Android Studio 4.2 Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174)

[✓] Android Studio (version 2020.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)

[✓] VS Code (version 1.59.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.25.0

[✓] Connected device (2 available)
    • iPhone (mobile) • XXXXXXXX-XXXXXXXXXXXXXXXX • ios            • iOS 14.7.1
      18G82
    • Chrome (web)    • chrome                    • web-javascript • Google
      Chrome 92.0.4515.131
    ! Error: iPhone is busy: Fetching debug symbols for iPhone. Xcode will
      continue when iPhone is finished. (code -10)

• No issues found!

No issues found!がやっと出た。

カテゴリー
学術

FlutterでFirebase Storage