使用Flutter設計一個好看的"我"頁面

程式設計實驗室發表於2021-06-18

近期遇到一些很煩的瑣事,狀態比較down,很多原本計劃好的事情都耽擱了,實在是難頂……

看到後臺一直有朋友問怎麼部落格和公眾號沒有更新,所以我忙完得閒就來更了!

前言

起因是最近重拾以前的舊專案(業餘做的,打算有機會自己運營起來)繼續完善,然後發現有些介面設計太粗糙了,實在不滿意(雖然是因為本來功能就不多),然後就著手開始優化~ 應該會寫成一系列文章,今天就從App的"我"頁面開始吧~

效果圖

話不多說,先上效果圖。

修改前頁面的頂部只有頭像、名稱、簽名三個元素,顯得很空;修改後增加了具有社交屬性的等級(經驗值)、動態、關注、粉絲等元素,還有二維碼圖示。看起來高階了一些~

修改前 修改後

不同的主題和夜間模式

看看不同主題下和夜間模式的效果(其實這個夜間模式還有待優化,感覺對比度太高)

主題1 主題2 夜間模式

頁面頭部改進思路

這個頁面的頭部我是參考了酷安App的設計,本來打算參考一下B站客戶端的,結果發現B站做得有點敷衍,醜就不說了(對我的審美而言),還沒有互動效果,感覺是程式設計師被deadline逼迫之下的產物(攤手)

先來看看我的套娃結構

其實很簡單,原本在放名稱和簽名的Column中間再插一個Container實現等級、經驗和進度條就ok了~

程式碼如下(由於篇幅關係,這裡只放關鍵程式碼):

Widget _buildHeader() {
    return Consumer<UserModel>(
      builder: (BuildContext context, UserModel userModel, Widget child) {
        var row = Row(
          children: <Widget>[
            ClipOval(child: daAvatar(userModel.user.avatar)),
            Expanded(
              child: Column(
                children: <Widget>[
                  // 使用者名稱
                  Text(userModel.isLogin ? userModel.user.nickname : '註冊或登入'),
                  // 等級、經驗
                  if (userModel.isLogin)
                    Container(
                      child: Column(children: [
                        Row(children: [
                            Text('LV3')),
                            Text('9372/27000'),
                          ]),
                        LinearProgressIndicator(value: 0.3, valueColor: AlwaysStoppedAnimation(Colors.blue)),
                      ]),
                    ),
                  // 個性簽名
                  Text(userModel.isLogin ? (userModel.user.signature ?? '沒有個性簽名') : '請先登入以獲得專屬服務~'),
                ],
              ),
            ),
            // 二維碼和右箭頭
            Icon(Icons.qr_code, color: Theme.of(context).primaryTextTheme.headline6.color),
            VerticalDivider(width: 10),
            Icon(Icons.chevron_right, color: Theme.of(context).primaryTextTheme.headline6.color),
          ],
        );
      },
    );
  }

動態、關注、粉絲元件設計

頁面頭部下方還有這個元件,用來顯示跟社交有關的資訊,這個元件是嵌入在下方的listview的,可以隨著頁面滑動。

實現很簡單,我直接放程式碼:

Widget _buildCard() {
  return Container(
    margin: EdgeInsets.fromLTRB(5, 10, 5, 10),
    child: Card(
      child: Container(
        margin: EdgeInsets.fromLTRB(5, 10, 5, 10),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            _buildNumberTextWidget('62', '動態'),
            _buildNumberTextWidget('18', '關注'),
            _buildNumberTextWidget('89', '粉絲'),
          ],
        ),
      ),
    ),
  );
}

_buildNumberTextWidget的實現如下:

Widget _buildNumberTextWidget(String number, String text) {
  var foreColor = Global.profile.darkMode ? Colors.white54 : Theme.of(context).primaryColor;
  return TextButton(
    child: Column(children: [
      Text(number, style: TextStyle(fontSize: 30, color: foreColor)),
      Text(text, style: TextStyle(color: foreColor)),
    ]),
    style: ButtonStyle(padding: MaterialStateProperty.all(EdgeInsets.symmetric(horizontal: 40))),
    onPressed: () => BotToast.showText(text: '妙啊'),
  );
}

因為要考慮到互動反饋,所以這裡我用了TextButton元件包裹內容。(注:TextButton元件是新版Flutter推出的,用以取代原本的FlatButton

互動效果

錄了個動畫,看看最終的互動效果:

差強人意吧(沒有UI,只能自己湊合搞一搞hh)

後話

時隔半年多,重新來搞Flutter,才發現Flutter已經更新到2.x版本了,新版dart語言也加了空安全特性,離kotlin/c#又進了一步,主流的第三方庫也都跟進了,都出了null safety版本的庫,總體開發體驗還是可以的~

不過做完的成品,給我的感覺,在效能上還是不如原生,很難做到像原生一樣的絲滑。不過這flutter搭介面是真的快,而且中文社群很活躍,在國內由於幾個大廠的牽頭,關注度很高,基本crud的這種場景,flutter毫無壓力的勝任,而且還能獲得比react native或者uniapp更高的效能和更好的使用者體驗。唯一的遺憾就是沒法做微信小程式了…

這個OneCat App在這麼長時間的開發和測試中,一直有各種小問題出現,總有地方不盡如人意,搞得我一度想用原生重寫了,不過後來想著flutter寫介面快,也就算了,寫著玩吧~

歡迎交流

程式設計實驗室專注於網際網路熱門新技術探索與團隊敏捷開發實踐,在公眾號「程式設計實驗室」後臺回覆 linux、flutter、c#、netcore、android、kotlin、java、python 等可獲取相關技術文章和資料,同時有任何問題都可以在公眾號後臺留言~

相關文章