学習ログ: Flutter入門してみる
まずはGet startedから
Flutterのインストール
macOS Catalina (10.15.7) に対してFlutterをインストール
Flutter SDKのインストールと配置
$ git clone https://github.com/flutter/flutter
$ sudo mv flutter /usr/local/
usr/local/flutter/bin
にPATHを通す
$ sudo vi /etc/paths
Flutter for web
まだベータ版であるが、Webアプリのビルドもできるようなので有効化してみる。
(これは興味本位)
$ flutter channel beta
$ flutter upgrade
$ flutter config --enable-web
Xcodeのセットアップ
$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
$ sudo xcodebuild -runFirstLaunch
$ sudo xcodebuild -license
Android Studio, Visual Studio Codeのセットアップ
Android StudioとVisual Studio Codeは既にインストール済みだったので、FlutterとDartのプラグインを追加した。
セットアップ状況の確認
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 1.24.0-10.2.pre, on Mac OS X 10.15.7 19H2 darwin-x64, locale ja)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 12.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.51.1)
[✓] Connected device (2 available)
• No issues found!
サンプルプログラムを動かす
Visual Studio Codeのコマンドパレットから Flutter: New Project
でテンプレートプロジェクトを作成。
エディタの右下からアプリの展開先を指定可能。
F5でビルド&実行。(今回はiOS Simulatorを使ってみた)
Write my first Flutter app
Write your first Flutter appを参考にHello worldしてみる。
テンプレートの main.dart
の中身を空にしてHello worldするコードを書いていく。
(Dartとエディタの雰囲気を掴むために写経していく)
- Hello worldレベルでは特にDart特有のクセとかは感じない
- インスタンス(表現合ってるかわかんない)作るときに
new
要らないんだ〜くらい
- インスタンス(表現合ってるかわかんない)作るときに
- プラグインのおかげで補完が効くのでスラスラ書ける
- UIはコードベースで作る
- フォーマットは
option+shift+F
- 普通はFormat on saveを設定する(私は諸事情により未設定)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter !!'),
),
body: Center(
child: Text('Hello World'),
),
),
);
}
}
pub.dev
Dartのパッケージはpub.devで配信されているらしい。
JSでいうところのnpm、.NETでいうところのNuGetという理解で合ってるかな?
pubspec.yaml
がNode.jsでいうところの package.json
に相当する。
dependenciesにパッケージ追加して下記コマンドを実行するとパッケージインストールされる。
$ flutter pub get
ステートフルなウィジェットを追加する
FlutterはWidget(コンポーネント)を並べてUIを作っていく。
stful
とタイプするとステートフルなWidgetのボイラープレートを展開してくれる。便利。
class extends StatefulWidget {
_State createState() => _State();
}
class _State extends State<> {
Widget build(BuildContext context) {
return Container(
);
}
}
ボイラープレートを埋めたのがこちら
class RandomWords extends StatefulWidget {
_RandomWordsState createState() => _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords> {
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
これで自作Widgetができた。実際に動かしてみる。
ListViewを作る
ListViewを配置し、itemを動的に生成して無限リストにする例
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
home: RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
_RandomWordsState createState() => _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = TextStyle(fontSize: 18.0);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Startup Name Generator'),
backgroundColor: Color.fromRGBO(100, 50, 100, 1),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return ListView.builder(
padding: EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
}
年内無料公開ということでKBOYさんの「KBOYのFlutter大学基礎編」を読ませていただく。ありがたや。
Dartの文法
Flutterの学習中にDartの細かな文法が気になってきたので調べることに。
特に気になっていたのが文字列内での変数展開int _counter = 0;
'$_counter' // こういうやつ
この変数展開の後続に文字列つなげられるのか?と疑問だったが ${}
も使えるらしいので多分こう書くんだと思う。
'${_counter}回'
あとは変数宣言のためのvar, dynamic, final, const。
DartのfinalはC#のconstだが、Dartのconstはimmutableにすることができる。
例えばリスト型の場合、finalで宣言しても中身は書き換え可能だが、constで宣言すると中身の書き換えもできなくなる。
final List<int> list1 = [1, 2, 3];
list1[0] = 100; // OK
const List<int> list2 = [1, 2, 3];
list2[0] = 100; // NG
なるほど、const constructorというものがありこれで定義するのか。
イニシャライザ
初期化時に変数をもらってフィールドにセットする場合、このように簡素に書ける。
class SampleWidget extends StatelessWidget {
// イニシャライザ
SampleWidget(this.name); // これだけでnameに値が代入されて初期化される
// フィールド
String name;
}
KBOYさんの「KBOYのFlutter大学基礎編」読了。
コード例、スクショGIF、参考文献等もあり入門用としてとてもわかりやすい内容でした。
monoさんの「Flutter FAQ 🇯🇵 よく目にするFlutterに関する疑問への私感」を読む。
そういえばmacOS Big Surにアップデートしたらflutter CLIが正常に動かなくなった。
$ flutter doctor
Building flutter tool...
Got socket error trying to find package file at https://pub.dartlang.org.
Error: Unable to 'pub upgrade' flutter tool. Retrying in five seconds... (9 tries left)
キャッシュを削除してみる。
$ rm -rf /path/to/flutter/bin/cache/
直らない・・・
実行環境の問題な気がしている。
ついに解決したああああああ!
会社の指定で入れていた AVG AntiVirus がブロックしていたっぽい。
例外リストに https://pub.dartlang.org を追加したら無事解決。良かった。。。
🎉🎉🎉
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.0.3, on macOS 11.2.3 20D91 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.55.0)
[✓] Connected device (1 available)
• No issues found!