[2022.10] O: Flutter初級者になる / KR1: 環境構築ができる / KR2: チュートリアルに従い簡単なアプリを作る / KR3: 入門書を1冊読む
2022.09.25 Flutter環境構築
この記事がとても参考になった
Xcodeのインストールが一番時間かかった
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.1, on macOS 12.6 21G115 darwin-arm, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.0)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.71.1)
[✓] Connected device (2 available)
[✓] HTTP Host Availability
• No issues found!
2022.09.26
Flutterを効率よく学ぶ順序があるか調査
VscodeでFlutter開発する
2022.09.27
VscodeのFlutter拡張を入れてプロジェクトを自動作成した。
カウンターアプリが簡単に起動した
公式のチュートリアルに沿ってアプリを作ってみる
Flutterのパッケージ管理
flutter pub add english_words
とやると、pubspec.yaml
が更新される
Dartのパッケージ群はpub.devで管理されている
2022.10.01
現場で使える Flutter開発入門 (Compass Booksシリーズ)
を購入。
サンプルコード
1章
vscodeでflutterの環境構築
analysis_options.yamlで静的解析を設定する
flutter_lints
こういうの地味に大事
デザインの共有はzeplin
ディレクトリ構成について
2章
Widget
「すべてのものはウィジット」らしい
指示に従い実装していく。
所々dartの書き方でわからない部分がある。
itemBuilder: (context, index) => Container(
returnを省略する記法っぽい
children: <Widget> [...]
型のアノテーションかな?
飽きたので公式チュートリアルに戻る
stfulでStatefulWidgetを自動生成してくれる、すごい
class RandomWords extends StatefulWidget {
const RandomWords({super.key});
State<RandomWords> createState() => _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords> {
Widget build(BuildContext context) {
return Container();
}
}
これはなんだろう
extends State<RandomWords>
Stateクラスを継承してるのはわかるけど<>が謎。
i ~/ 2
は剰余(mod)
Viewオブジェクトの使い方がなんとなくわかってきた。
builderファクトリーなのか
contextはどんなオブジェクトなのだろう
XxxView.builder(
itemBuilder: (context, ...) {return ...}
)
永遠にスクロールできるViewが実装できた。
次はいいねができるようにする。
class RandomWords extends StatefulWidget {
const RandomWords({super.key});
State<RandomWords> createState() => _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18);
final _saved = <WordPair>[];
Widget build(BuildContext context) {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return const Divider();
final index = i ~/ 2; // 剰余
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
final alreadySaved = _saved.contains(_suggestions[index]);
return ListTile(
title: Text(
_suggestions[index].asPascalCase,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
semanticLabel: alreadySaved ? 'Remove from saved' : 'Save',
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(_suggestions[index]);
} else {
_saved.add(_suggestions[index]);
}
});
},
);
});
}
}
いいねが保持できるようになった
三項演算子
alreadySaved ? Icons.favorite : Icons.favorite_border
ふと気づいたけど、RandomWordsと_RandomWordsStateの責務の違いがよくわからない。
_RandomWordsStateのbuildにほぼ全ての処理を実装しているし、Widgetを返しているので、Stateなのか?
2022.10.02
BuildContextはWidgetに自分の「位置」を教えるものらしい。親ノード・子ノードなどWidgetツリー中での他のWidgetとの関係性
ついにページ遷移
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Name Generator'),
actions: [
IconButton(
onPressed: _pushSaved,
icon: const Icon(Icons.list),
tooltip: 'Saved Suggestions',
)
],
),
appBarにハンバーガーメニューを追加
ここをonPressすると_pushSavedを呼ぶ
void _pushSaved() {
Navigator.of(context).push(MaterialPageRoute<void>(builder: ((context) {
final tiles = _saved.map((pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
));
});
final divided = tiles.isNotEmpty
? ListTile.divideTiles(tiles: tiles, context: context).toList()
: <Widget>[];
return Scaffold(
appBar: AppBar(title: const Text('Saved Suggestions')),
body: ListView(children: divided),
);
})));
}
まだよくわからないけど、
Navigator.of(context).push(...)
を使うと遷移できることはわかった。
AppBarのテーマ変更
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: Colors.white,
foregroundColor: Colors.blueAccent,
),
),
home: const RandomWords(),
);
}
}
チュートリアル完了、、!
気になったこと調べる
FlutterのWidget一覧
Scaffold
レイアウトを司るWidgetの全体像
- Single Child Layout
- Multi Child Layout
(引用:https://codezine.jp/article/detail/14711)
(引用:https://flutter.ctrnost.com/basic/layout/layout/)
dartの書き方
- anonymous functionが引数の時にarrowで書くと便利
flybyObjects.where((name) => name.contains('turn')).forEach(print);
-
null以外の全てのDartオブジェクトはObject classを継承している
https://api.dart.dev/stable/2.18.2/dart-core/Object-class.html -
コンパイル時にconstant construct
https://dart.dev/guides/language/language-tour#classes
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
assert(identical(a, b)); // They are the same instance!
書籍2章に戻る
右下のFloatingActionButtonを作る
Scaffold(
appBar: ...,
body: ...,
floatingActionButton: ここに実装する
)
Column Widgetを使って縦に並べる
Column(
children: <Widget>[...]
)
setStateを使うとUIの更新が走る
FloatingActionButton(
heroTag: 'grid_off',
onPressed: () {
if (_columnsCount > 2) {
setState(() {
_columnsCount--;
});
}
},
2022.10.16
Riverpodで状態管理
Providerパッケージと同じ人が作ったライブラリ
Riverposが提供するProviderの種類
Streamクラスってなんだろ
Iterableのasync版っぽいその他
- Web上でdartを実行できる環境
2022.10.31
達成率
- O: Flutter初級者になる 70%
- KR1: 環境構築ができる 100%
- KR2: チュートリアルに従い簡単なアプリを作る 80%
- KR3: 入門書を1冊読む 40%
反省
10月後半は時間が取れなかった。
「初級者」がどういう状態か定義するのに時間がかかった。(やってみないと分からないのでそれはそう)