用 Flutter 開發一個 Android App 吧 - Day12

Build Android app with Flutter - Day12

Posted by Bobson Lin on Saturday, September 21, 2019

Day 12. 關於頁面

本系列同步發表在 第11屆鐵人賽

關於頁面(AboutPage)

關於頁面中,目前只想顯示些簡單的資訊,App Icon 跟 版本資訊。

就先顯示這兩個東西吧~

day12-1.png

App 資源管理

我們先不急著看程式碼,首先先想一個問題。

App 有時需要用到些內嵌的檔案。
例如,Logo、背景圖之類的檔案,在 Flutter 都稱為資源(asset)。

而很方便的是,Flutter 有一種方法能很快的讓它們加入到 App 中。
就是在 pubspec.yaml 檔案中描述要加入的 assets。

day12-2.jpeg

要在 lib/ 底下的 *.dart 都裡能使用到 assets,主要有幾個步驟:

  1. 先像上圖那樣在專案中新增 assets 資料夾,並將圖片資源放在其中。
  2. pubspec.yaml 加入 assets 描述。
  3. 在 Flutter SDK 裡最常使用 Image.assetAssetImage 來顯示圖片。

Show me the code~~

講了半天,還是實際上看些程式碼感受一下比較快。

import "package:flutter/material.dart";

class AboutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("About"),
      ),
      body: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints viewportConstraints) {
          return SingleChildScrollView(
            child: ConstrainedBox(
              constraints: BoxConstraints(
                minWidth: viewportConstraints.maxWidth,
                minHeight: viewportConstraints.maxHeight,
              ),
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 24.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[

                        // vvv Assets 圖片用在這裡喔~~
                        CircleAvatar(
                          backgroundImage:
                              AssetImage("assets/images/gitme-reborn-logo.png"),
                          radius: 40.0,
                        ),
                        SizedBox(height: 8.0),
                        Text("gitme reborn",
                            style: Theme.of(context).textTheme.title),
                        SizedBox(height: 4.0),
                        Text("0.0.1",
                            style: Theme.of(context).textTheme.subtitle),
                      ],
                    ),
                    Column(
                      children: <Widget>[
                        Text("Made by BbsonLin",
                            style: Theme.of(context).textTheme.caption),
                        Text("License MIT",
                            style: Theme.of(context).textTheme.caption),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

雖然只有 60 行,但 LayoutBuilderConstrainedBox 這兩位 Widget 挺陌生的…

這邊就需要解釋一下了,在 SingleChildScrollView 文件中有寫到,SingleChildScrollViewColumn 這兩個 Widget 其實有點衝突。
Column 會撐畫面滿到盡可能的大,而 SingleChildScrollView 會提供無限的空間給 child

那這樣豈不是就沒有任何限制了嗎!?
對,所以你給 Column crossAxisAlignment: CrossAxisAlignment.center,它也不知道該怎麼置中…

解決的方法就是給它 限制

文件裡給的方法是利用 LayoutBuilder builder 函數中的 viewportConstraints 參數來搭配 ConstrainedBoxSingleChildScrollViewchild 限制,以達成 Column 置中。

這邊是我個人的理解,如果有理解錯誤,歡迎底下留言告知~~

App 版本

這邊還有一向問題要解決的,就是版本 0.0.1 目前是寫死在程式碼裡的,要怎麼讓它動態的知道我們版本更新了呢?

還記得在 Day 5 時,我們有使用過第三方套件來處理登入 modal。
我們必須在 pubspec.yaml 的 dependency 裡加上 [pacakge_name]: [semantic version]

基本上,我們撰寫的 gitme_reborn 的 pubspec.yaml 在最前面就有一個欄位為 version

day12-3.jpeg

那麼我們在 App 運行時怎抓到它的值呢?

其實 Flutter Team 有維護一個 package 為 package_info,就是在提供此功能的套件。

day12-4.jpeg

成果

day12-5.gif

呼~ 真的還滿多細節需要注意的…
明天會是 UI 最後部份,有些小地方需要加強的
明天接續囉~~

參考