本系列同步發表在 個人部落格,歡迎大家關注~
登入按下登入按鈕後的時候,需要有一個 Loading 的 Modal。
如圖
而在 Flutter 所提供的 Material 元件裡找不到能直接使用的類似元件,這時候就到 Dart 的套件管理網站 https://pub.dev/flutter 去找找有沒有別人寫好的套件吧~
滿幸運的是,我找到一個名為 flutter_progress_hud 的套件,整體狀態有 90 分呢~
照著文件範例修改一下 lib/pages/login.dart
圖小,可點擊圖片看 Commit
--
另外,登出的話需要跳出一個讓使用者確定登出的 AlertDialog。
如圖
AlertDialog 在 Flutter 就有提供對應的 Material 元件,修改 lib/pages/home.dart
圖小,可點擊圖片看 Commit
小提醒:
pubspec.yaml
dependencies 裡面需要新增flutter_progress_hud: ^1.0.2
這套件。- 參考: 官方文件 - Using packages
--
接下來,我們把後續的主頁面的排版先架構出來吧。
在 Day3 主頁面時可以看到我笨笨的寫了好幾個 ListTile
和 Divider
,這樣的作法也許在作 Demo 時還可以使用,但實際上若有數十個、數百個不就完了嗎?
回想一下 Day3 講的 Think declaratively
,其他頁面可以稍微改良一下,我們可以先用 暫時宣告的變數 當作狀態,在 Widget build(BuildContext context)
時可以直接使用 暫時宣告的變數 來構建畫面。
什麼意思呢~ 接著往下看。
lib/pages/repo.dart
import 'package:flutter/material.dart';
class RepoPage extends StatelessWidget {
final List repoList = [
{
"title": "BbsonLin/gitme_reborn",
"description": "No description provided.\n\n★ 0",
"lang": "● Dart"
},
{
"title": "BbsonLin/ithome-ironman",
"description": "No description provided.\n\n★ 0",
"lang": ""
},
{
"title": "BbsonLin/flask-request-logger",
"description":
"A Flask extension for recording requests and responses into database\n\n★ 3",
"lang": "● Python"
},
];
@override
Widget build(BuildContext context) {
return Container(
child: ListView.separated(
itemCount: repoList.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(repoList[index]["title"]),
subtitle: Text(repoList[index]["description"]),
trailing: Text(repoList[index]["lang"]),
isThreeLine: true,
contentPadding: EdgeInsets.all(16.0),
onTap: () {},
);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 0.0),
),
);
}
}
宣告 final List repoList
來暫時當作未來會拿到的資料包(狀態),而且在 UI 上面採用 ListView.separated
這方法可以更快速達成想要的畫面。
程式碼看起來是不是更簡潔有力點了呢?
那麼這兩個頁面其實就是依樣畫葫蘆,偷懶一下就不貼程式碼上來了~?
詳細 commit 可以點擊成果 GIF 觀看~
小提醒:
這邊我在
StatelessWidget
裡用了 「暫時宣告的變數」 來儲存狀態,看似沒什麼問題,但想要達成交互式(Reactive) UI 需要使用StatefulWidget
,後續會慢慢使用到它~
今日成果