[譯] 挑戰 Flutter 之 WhatsApp

僱個城管打天下發表於2018-08-13

[譯] 挑戰 Flutter 之 WhatsApp

Flutter Challenges 是一項嘗試利用 Flutter 重新建立特定的應用程式UI或設計的挑戰。

此次挑戰將嘗試 Whatsapp Android 應用程式的主介面。請注意將重點放在 UI 上而不是實際獲取訊息。

開始

WhatsApp 的主介面包括:

  1. 一個帶有搜尋操作和選單的 AppBar
  2. 在 AppBar 的底部有四個標籤
  3. 一個用於拍照的相機標籤
  4. 一個用於多種用途的 FloatingActionButton
  5. 一個“聊天”標籤可檢視所有對話
  6. 一個“狀態”選項卡可檢視所有狀態
  7. 一個“打電話”選項卡可檢視所有的通話記錄

專案設定

讓我們建立一個名為 whatsapp_ui 的 Flutter 專案並刪除所有預設程式碼,只留下一個帶有預設應用欄的空白螢幕。

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("WhatsApp"),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            
          ],
        ),
      ),
    );
  }
}
複製程式碼

The AppBar

AppBar 具有應用程式的標題,以及兩個操作:搜尋和選單。

將其新增到 AppBar 中,

appBar: new AppBar(
  title: new Text("WhatsApp", style: TextStyle(color: Colors.white, fontSize: 22.0, fontWeight: FontWeight.w600),),
  actions: <Widget>[
    Padding(
      padding: const EdgeInsets.only(right: 20.0),
      child: Icon(Icons.search),
    ),
    Padding(
      padding: const EdgeInsets.only(right: 16.0),
      child: Icon(Icons.more_vert),
    ),
  ],
  backgroundColor: whatsAppGreen,
),
複製程式碼

程式碼結果如下:

[譯] 挑戰 Flutter 之 WhatsApp

現在繼續

The Tabs

tabs(選項卡)是 AppBar 的簡單擴充套件,Flutter 使它們非常容易實現。

AppBar 有一個“底部”欄位,用於儲存我們的標籤:

bottom: TabBar(
  tabs: [
    Tab(icon: Icon(Icons.camera_alt),),
    Tab(child: Text("CHATS"),),
    Tab(child: Text("STATUS",)),
    Tab(child: Text("CALLS",)),
  ], indicatorColor: Colors.white,
),
複製程式碼

此外,我們需要一個 TabController 來實現這一點。

建立一個新的 TabController。

TabController tabController;

@override
void initState() {
  // TODO: implement initState
  super.initState();

  tabController = TabController(vsync: this, length: 4);

}
複製程式碼

現在將該控制器新增到 TabBar 的 “controller” 欄位中。

bottom: TabBar(
  tabs: [
    Tab(icon: Icon(Icons.camera_alt),),
    Tab(child: Text("CHATS"),),
    Tab(child: Text("STATUS",)),
    Tab(child: Text("CALLS",)),
  ], indicatorColor: Colors.white,
  controller: tabController,
),
複製程式碼

而對於 TabBarView

body: TabBarView(
  controller: tabController,
  children: [
    Icon(Icons.camera_alt),
    Text("Chat Screen"),
    Text("Status Screen"),
    Text("Call Screen"),
  ],
),
複製程式碼

[譯] 挑戰 Flutter 之 WhatsApp

現在,在轉到各個頁面之前,我們將新增選項卡所代表的頁面。用以下方法切換腳手架的現有“正文”程式碼:

body: TabBarView(
  children: [
    Icon(Icons.camera_alt),
    Text("Chat Screen"),
    Text("Status Screen"),
    Text("Call Screen"),
  ],
),
複製程式碼

子項代表選項卡所用的頁面。現在整個頁面都是一個 Text 小部件。

懸浮按鈕

Floating Action Button 根據螢幕上的頁面而變化。

首先在腳手架中新增一個 FloatingActionButton。

floatingActionButton: FloatingActionButton(
  onPressed: () {
  },
  child: fabIcon,
  backgroundColor: whatsAppGreenLight,
),
複製程式碼

“fabIcon” 欄位只儲存要顯示的圖示,因為我們需要根據顯示的螢幕更改顯示的圖示。

要監聽選項卡選定的更改,需要給 TabController 新增一個監聽器。

tabController = TabController(vsync: this, length: 4)
  ..addListener(() {
    
  });
複製程式碼

現在,當標籤控制器實現頁面已更改時,請更改 FAB 圖示。

tabController = TabController(vsync: this, length: 4)
  ..addListener(() {
    setState(() {
      switch(tabController.index) {
        case 0:
          break;
        case 1:
          fabIcon = Icons.message;
          break;
        case 2:
          fabIcon = Icons.camera_enhance;
          break;
        case 3:
          fabIcon = Icons.call;
          break;
      }
    });
  });
複製程式碼

[譯] 挑戰 Flutter 之 WhatsApp

繼續,

聊天介面

聊天螢幕有一個我們需要顯示的訊息列表。要建立訊息列表,我們使用 ListView.builder() 並構造我們的專案。

讓我們來看看聊天介面的列表項。

[譯] 挑戰 Flutter 之 WhatsApp

最外面的小部件是一行圖示和另一行

第二行內部是一列,包含一行和一個文字小部件。

該行具有標題和訊息日期。

讓我們構建一個聊天項模型作為用於儲存列表項詳細資訊的類。

class ChatItemModel {
  
  String name;
  String mostRecentMessage;
  String messageDate;
  
  ChatItemModel(this.name, this.mostRecentMessage, this.messageDate);
  
}
複製程式碼

現在,為簡潔起見,我省略了新增個人資料圖片。

itemBuilder: (context, position) {
  ChatItemModel chatItem = ChatHelper.getChatItem(position);

  return Column(
    children: <Widget>[
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          children: <Widget>[
            Icon(
              Icons.account_circle,
              size: 64.0,
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment:
                          MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Text(
                          chatItem.name,
                          style: TextStyle(
                              fontWeight: FontWeight.w500,
                              fontSize: 20.0),
                        ),
                        Text(
                          chatItem.messageDate,
                          style: TextStyle(color: Colors.black45),
                        ),
                      ],
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 2.0),
                      child: Text(
                        chatItem.mostRecentMessage,
                        style: TextStyle(
                            color: Colors.black45, fontSize: 16.0),
                      ),
                    )
                  ],
                ),
              ),
            )
          ],
        ),
      ),
      Divider(),
    ],
  );
},
複製程式碼

建立第一個列表後,結果如下:

[譯] 挑戰 Flutter 之 WhatsApp

我們可以類似地在其他螢幕上的螢幕上建立其他選項卡。完整的示例託管在GitHub上。

GitHub 連結 : github.com/deven98/Wha…

感謝您閱讀此 Flutter 挑戰。隨意提及您可能想要在 Flutter 中重新建立的任何應用程式。如果你喜歡它,一定要留下掌聲,再見。

不要忘了:The Medium App in Flutter

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章