TIGの伊藤真彦です。
フロントエンドアプリケーションの開発においてVue、Reactと触ってきましたがFlutterの開発も始めました。モバイルアプリ、Webアプリ、更にはデスクトップアプリへの高いポータビリティが期待できる、Adobe XDでのデザインを高速にアプリケーションに反映できる、といった期待値が高いことが選定の理由です。
フューチャーではDart/Flutter連載で様々なネタを取り上げましたが、汎用的なハウツー記事が意外と少なかったため書いてみました。
Flutterとは
FlutterはDart言語で実装されたアプリケーションフレームワークです。
元々はAndroid、iOS向けのモバイルアプリケーションを実装するためのSDKでしたが、Flutter on the web、Flutter on Desktopの公開により、Flutterで作っておけばどのようなプラットフォームであってもアプリケーションをリリースできる、という環境が整備されました。
執筆時点の2021年末ではFlutter on Desktopはまだリリースから日が浅いですが、モバイルでもPCでも使える共通コンポーネントを作りたい、というニーズを強力にサポートしてくれる事が期待できます。
Flutterのインストール
Flutterは公式サイトからSDKをインストールすることでflutter
コマンドが利用できるようになります。flutter
コマンドはアプリケーションの初期構築、起動、依存モジュールの管理を行うことができます、npm
コマンド+任意のフレームワークのCLIコマンドのような存在ですね。
インストールページから各OS向けのSDKがダウンロードできます。2021年現在ではリッチなインストーラではなく、ダウンロードしたファイル一式を解凍後、任意の場所に配置し、自力でパスを通す必要があります。
下記のようなコマンドを.bash_profile
等のファイルに記載してください。
export PATH="$PATH:[flutterフォルダが格納されているディレクトリ]/flutter/bin" |
ファイルの中身は単一のバイナリではなく、サンプルコードやREADMEなど一式揃っており一瞬驚きますが、それら全てが必要です。
パスを通すとflutter
コマンドが利用できるようになります。
$ flutter --version |
doctorコマンドの利用
Flutterにはdoctorコマンドというものが存在します。これは各プラットフォームにおける環境構築が終わっているかを確認できるコマンドです。
Flutterでモバイルアプリケーションを開発する場合、iOSではXcode、AndroidではAndroid Studioを利用してアプリケーションをビルド、デバッグすることになります。これら必要な開発ツールが揃っているかを確認し、何が必要かを教えてくれるのがdoctor
コマンドです。
flutterのインストールが終わったら、doctor
コマンドを実行し、開発したいプラットフォーム向けの準備が終わっているかを確認しましょう。私はAndroid, iOS向けアプリケーションの開発経験が既にあったため、Android StudioのConfigを少し変更するだけで下記のように全ての準備が終わりました。
$ flutter doctor |
アプリケーションを新規作成する
環境構築が終わったら、アプリケーションを作成します。
どのような開発経験の方でも手早く試せるため、Flutter on the Webでの開発前提で説明します。Flutterはflutter create
コマンドで、アプリケーションの雛形を生成できます。
Flutterのプロジェクト名は-
を含めることができません。
Androidアプリケーションとして公開する際のapplicationId
の命名規約に抵触することから-
が利用できないようです。多くのflutter向けOSSパッケージは_
区切りのスネークケースなので、それに倣うのが良いでしょう。
flutter create hello_world |
コマンドを実行すると様々なファイルが自動生成され、下記のような案内が表示されます。
All done! |
指示通りにコマンドを実行するとサンプルアプリケーションが起動します。
Flutter on the Webが存在するおかげで、Xcode、Android Studioが無い状態でもとりあえず動かすことは可能です。
cd hello_world |
よくある公式ロゴ入りのHello Worldページではなく、ボタンを押すとカウンタの数が増えるというインタラクティブなデモアプリが起動するのが特徴的です。
VueやReactに慣れているとlocalhost:3000
やlocalhost:8080
で起動しないのが違和感を覚えますが、Flutter on the Webの場合空いている適当なポートで起動します。
ポート番号を指定することも可能です。
flutter run --web-port 8080 |
モバイル、デスクトップの開発環境が整備されている場合、-d
オプションで起動するプラットフォームを選択できます。all
で実行可能な全てのプラットフォーム向けに同時起動できます、楽しいですね。
flutter run -d all |
アプリケーションを開発するための知識
アプリケーションを起動できたら、デモアプリケーションを編集し、任意のアプリケーションを開発していきます。
lib/main.dart
を編集することでアプリケーションを開発できます。
生成されたアプリケーションのmain.dart
を見てみます。
import 'package:flutter/material.dart'; |
Flutterアプリケーションは最初に説明した通りDartで実装されたアプリケーションであり、更にはそれがFlutterアプリとして抽象化されているため、慣れるまでは少し時間がかかるかもしれません。
まずは雰囲気で最初に表示された画面のコンポーネントと、画面の状態を管理するステート、ボタンを操作した際にカウンタをインクリメントする関数が書いてあることを感じてみるくらいの所からスタートすることになるかなと思います。
ここからDartの文法、Flutterのお作法を学んでいきましょう。
ウィジェットについて
Flutterアプリケーションは画面のコンポーネントをウィジェットという単位で開発します。
モバイルアプリが出自であるため、Vue、ReactなどHTMLを意識したコンポーネントの書き方に慣れたWebフロントエンジニア出身の人よりはSwiftのようなモバイルアプリ開発に慣れている方の方が親しみを覚えやすい書き方をする事になります。
Flutter公式ドキュメントからどのようなウィジェットが存在しているのかを一通り眺めておくとやりたい事と出来る事のイメージが掴みやすいです。Basics、Layout、Textあたりから攻めてみて、サーバーサイドから取得した情報を取得したい、といった要望に応えるためにAsync Widgetsあたりに早期に触れるような流れが自然でしょうか。
Flutterレイアウト入門、Flutter ウィジェットテスト入門も合わせてお読みください。
Stateについて
他のフレームワークでのフロントエンドアプリケーションの開発で馴染みがある人がいるかもしれませんが、Stateは日本語にすると「状態」を意味します。ウィジェットのStateとは文字通りウィジェットが持っている状態の変化を管理するための概念です。ユーザーの操作によって変更が起こりうる要素、外部APIから取得したデータなど、動的に変化する情報をStateとして扱い、管理します。
デモアプリではユーザーがボタンを押した時に画面中央のカウントが更新される部分が該当します。int _counter = 0;
で宣言した変数_counter
にカウント情報を保存し、状態を更新し、画面を再描画するために、setState()
関数の内部で変数の値を更新する関数、_incrementCounter()
が実装されています。
Reactなど近年のフロントエンド フレームワークでは、画面の状態を管理することで、状態が更新された場合コンポーネント単位での再描画を行う、更新のないコンポーネントは再描画しない、という必要最小限の画面更新を行う仕組みでアプリケーションのパフォーマンスが高くなるように設計されています。Flutterもその仕組みを採用しており、状態管理を行っているということですね。FlutterではStateを持たないStatelessWidget
、State管理の仕組みを備えたStatefulWidget
の2種類のウィジェットが存在します。
状態管理については武田さんのアドベントカレンダー記事に詳しいです。
パッケージ管理について
デモアプリから発展して高度なアプリケーションを開発するにあたり、何らかのライブラリを導入する事になるでしょう。
FlutterではFlutterに向けて作られたものは勿論、Dart向けのライブラリをインポートできます。Flutterアプリでは依存モジュールをpubspec.yaml
というファイルで管理しています。Node.jsでいうところのpackage.json
、Goでいうところのgo.mod
のようなファイルです。ライブラリを追加、削除するにはflutter pub
コマンドを利用します。
例えばFlutterでは拡大、縮小可能な画像を表示するphoto_viewパッケージがあります。インポートするだけで画像をカッコよく表示するウィジェットが使えるようになります。
flutter pub add
コマンドでパッケージをインストールします。Dartパッケージのサイトでは簡単なコマンドであってもインストールの手法、実装サンプルが整備されています。
サンプルだけでなく、APIリファレンスも見れば使い方は概ね分かると思います。
flutter pub add photo_view |
パッケージをインストールし、import行を追加することで、パッケージの機能やウィジェットが使えるようになります。
import 'package:photo_view/photo_view.dart'; |
photo_view
をimportするとウィジェットとしてPhotoView()
を利用できるようになります。
|
実際にはレイアウトを調整するため他のウィジェットと組み合わせて使うことになると思いますが、Flutterではこのような形でサードパーティのモジュールを簡単に導入できます。
導入したパッケージを削除する場合はremove
コマンドが利用できます。
dart pub remove photo_view |
他の人が作成したFlutterアプリケーションをGit cloneするなどの形で開発する場合は、flutter pub get
コマンドで依存モジュールをダウンロードできます。
flutter pub get |
アプリケーションのビルド
アプリケーションが完成したら、対象のプラットフォーム向けにビルドします。
ビルドにおいてもスマートフォンアプリとしてビルドする場合はXcode, Android Studioでの環境構築が必要です。ここでもFlutter on the Webでの例を記載します。
アプリケーションのビルドはflutter build
コマンドで行います。
flutter build web |
対象プラットフォームを指定してビルドコマンドを実行すると、ビルドが開始されます。
$ flutter build web |
コマンド実行が成功するとbuild
フォルダに成果物がビルドされます。
webフォルダの中身にはindex.html
をはじめ各種ファイルが生成されています。
これら一式をFirebaseやGitHub Pages静的サイトとしてホスティングできるサービスにそのまま配置するような使い方でFlutterアプリをデプロイできます。
ビルドされたindex.html
をそのままダブルクリックしてブラウザで開いても正常に動作しません。これはmain.dart.js
がサーバーでホストされている前提で動こうとするためです。
実際にデプロイしてみても良いですが、環境を用意するのが面倒な場合は、Goのサーバーの管理画面をFlutter Webで作ってみるための調査の「Goのアプリケーションに組み込む」のようにlocalhost
でホスティングするような手法で試すこともできます。
まとめ
Flutterの環境構築から開発手法、ビルドまでの流れを紹介しました。
高度なアプリケーション開発のtipsやAndroid、 iOS向け、更には各OSのデスクトップアプリでの環境構築、ビルド、リリース手法など深堀りする余地はたくさんありますが、ひとまず流れとしては以上になります。