Flutter 學習筆記

筆記,起步走

Posted by willsbor Kang on 2021-09-24

稍微看 Flutter 有一段時間了。
也蠻認同一個想法,

雖然跨平台語言不能解決平台上實作細節的差異,
但就考慮純粹「功能邏輯」或「商業邏輯」的共用,
似乎就有蠻大的效益!

原本想要直接研究 iOS 和 Flutter 之間的轉接。
但發現好像不先搞懂 Flutter 的設計邏輯,確實寫作起來有點綁手綁腳。

安裝

這部分我忘了紀錄,但目前應該在網路上都還容易找到文章。

開專案

同上。(掩面

程式語感

忘了在哪裡看到,Flutter 本身是像一顆 Tree, 從 main 開始就是一個 state 的節點,然後再包裝 n 個 state 節點,每個子節點可能又在包裝 0~n 個。
之所以頓悟,是因為遇到了下面一個問題。

頁面間的資料如何傳遞

寫應用軟體一定會遇到的問題。
找了一些文章看到,他們會建立一個 InheritedWidget 的子類別,然後再用他包裝子節點 (state)。

例如:

1
2
3
4
5
6
7
8
9
10
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MorningDataProvider(child: MaterialApp(
title: 'WelCome to Flutter',
home: Scaffold(body: BottomNavigationController()),
));
}
}

變成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyApp extends StatelessWidget {
final eventManager = EventManager();

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MorningDataProvider(
child: MaterialApp(
title: 'WelCome to Flutter',
home: Scaffold(body: BottomNavigationController()),
),
eventManager: eventManager,
);
}
}

其中 MorningDataProvider 就是一個 InheritedWidget
因此下面的子結點,都可以藉由

1
context.dependOnInheritedWidgetOfExactType<MorningDataProvider>();

拿到 MorningDataProvider 的實體。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
class _HomePageState extends State<HomePage> {
List<EventCell> suggestions = List(0);

@override
Widget build(BuildContext context) {
final eventManager = context.dependOnInheritedWidgetOfExactType<MorningDataProvider>().eventManager;

suggestions = eventManager.events.map((e) => e.toCell()).toList();

...
}
}

但老實說我不是很喜歡這樣的模式XD。有點物件相依,不過還在學習語言,還是得先把成見忘掉。

簡單的頁面資料傳遞

可以用 push + await 去等待 pop 回來的資料
例如:

1
2
3
4
5
6
7
8
9
10
11
12
final addResult = await Navigator.push(
context,
MaterialPageRoute(
fullscreenDialog: false,
builder: (context) => CreateEventPage(),
),
);
if (addResult != null) {
setState(() {
eventManager.events.add(addResult);
});
}

在另一個頁面丟資料回去時

1
2
3
4
5
var transferData = EventData(
nameController.text,
categoryController.text,
DateTime.parse(dateController.text));
Navigator.pop(context, transferData);

在 swift 5.x 終於也有 async/await 這個功能了,哈

加入一個 sub library at pubspec.yaml

我是在處理 DateTimeField 的時候遇到的問題
因為有簡單的 TextFormField,但一直找不到時間的 input 要怎麼輸入,後來才 google 到。

  1. 先在 pubspec.yaml 的 dependenies: 加入需要的 library
    e.g. datetime_picker_formfield: ^2.0.0
  2. 然後就可以用了

目前覺得寫起來有點雜亂,可能還沒抓到感覺

Reference

https://iter01.com/436993.html
https://iter01.com/434210.html
https://www.woolha.com/tutorials/flutter-date-time-datetime-picker-input-example