Open9

Flutterの基礎的なことをまとめていく

Kazufumi SuzukiKazufumi Suzuki

UdemyのFlutterコースThe Complete 2021 Flutter Development Bootcamp with Dartで覚えておきたいことをまとめていく。

去年8割方進めたが、割と忘れているのでもう一週しながら自分の理解を深めるためここに書き溜めておく。
^が終わり次第知りたいことは下記2つ。

  • テスト
  • 設計やアーキテクチャ(実プロジェクトでどうやってレイヤー分割していくか)

GoogleのFlutterチームとコラボして作られていることもあって質はとてもよい。そして英語も聞き取りやすいし、聞き取れなくても動画でだいたいのことは理解できる。

Kazufumi SuzukiKazufumi Suzuki

Flutter概要

  • 1コードベース(言語はdart)でiOS、Android、Web、デスクトップアプリを作れる。
  • Widgetと呼ばれるパーツをレゴのように組み合わせることでUIを組める。
  • ホットリロード機能でコード修正した直後に画面に反映される。 > 開発効率がめちゃ高い。
Kazufumi SuzukiKazufumi Suzuki

Hello World

各種設定は割愛。

Android Studioを開き、Create New Flutter Project>Flutter Appを選択>Project Nameを入力してFinishボタンを押すと雛形プロジェクトができる。

実際に記述するソースコードはlibの中に収める。
利用ライブラリはpubspec.yamlファイルに書く。

当面はlib/main.dartをいじっていく。

lib/main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      title: 'Flutter Demo',
      home: Text('Hello World!'),
    ),
  );
}

main関数はエントリーポイント、緑色の再生ボタンを押すとここを起点に実行される。
runAppはドキュメント(Inflate the given widget and attach it to the screen.)にあるように、引数で与えられたWidgetを展開して画面に描画する関数。
^を実行するとpixel 4aでは下記のようになる。

どうでもいいがエミュレータより実機で実行したほうがアプリ作ってる感が出るのでおすすめ。特にAndroidのビルドは早いのでストレスが少ない。

とりあえずハロワまでできた。

Kazufumi SuzukiKazufumi Suzuki

Scaffoldと画像の利用

ハロワのアプリだと流石に不格好。アプリの基本となるScaffoldWidgetを使うとアプリバー(タイトルなどを表示)とbodyを表示できる。

lib/main.dart
import 'package:flutter/material.dart';

// main関数はエントリーポイントとなる
void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("I Am Poor"),
          backgroundColor: Colors.green,
        ),
        body: Center(
          child: Image(
            image: AssetImage("images/poor.jpg"),
          ),
        ),
      ),
    ),
  );
}

アプリに画像を表示させたい場合はpubspec.yamlのflutter>assets下にディレクトリを指定する。
このファイルの反映はPub getで行う。

pubspec.yaml
flutter:
  # 画像やコンテンツをアプリで使う場合はこちらにディレクトリのパスを指定する
  assets:
    - images/

アプリアイコンの変更方法はこちらの記事がとても参考になった。

githubレポジトリ

実行した画面は下記の通り。それっぽくなってきた。

Kazufumi SuzukiKazufumi Suzuki

Widgetの説明

  • Flutterはpaddingや左寄せなどの制約も含め、全てのUIをWidgetで表現する。

  • WidgetはMaterialAppを頂点としたツリー構造になる。(動画ではWidgetツリーと呼ばれていた)

    • たとえば先ほどの画像表示するだけのアプリのWidgetツリーはこんな感じ。
  • Widgetには一つの子どもを持つSingle-child layout widgetsと複数の子どもをもつMulti-child layout widgetsに分けられる。

    • Single-child layout widgetschildプロパティを持つ
      • 代表的なもの:Center、Containerなど
    • Multi-child layout widgetschildrenプロパティを持つ
      • 代表的なもの:Row、Columnなど

とにかくWidgetをレゴブロックのように
組み合わせてUIを作っていく。

講座では下記のような画像が課題として出てきて、そのコードを書くというものがあった。

コードはこんな感じ。

lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.teal,
        body: SafeArea(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Container(
                color: Colors.red,
                width: 100.0,
              ),
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Container(
                    color: Colors.yellow,
                    height: 100.0,
                    width: 100.0,
                  ),
                  Container(
                    color: Colors.green,
                    height: 100.0,
                    width: 100.0,
                  ),
                ],
              ),
              Container(
                color: Colors.blue,
                width: 100.0,
              ),
            ],
          ),
        ),
      ),
    );
  }
}
  • 全体から詳細に向かってネストが深くなっていく。
  • ネストが深くなると読みづらいが、コードの左側の+ーボタンで折り畳めるのが便利。
  • このUIの記述方法を宣言的UIという。(SwiftUIも同じ)
Kazufumi SuzukiKazufumi Suzuki
  • SafeArea
    • 画面のノッチなどで見えなくなる部分を除いた表示領域に限定するWidget
Kazufumi SuzukiKazufumi Suzuki

ホットリロードするとbuildメソッドが毎回呼び出される。
ホットリスタートすると状態(カウンターアプリの数値など)がリセットされる。