- 原文地址:Flutter Challenge: WhatsApp
- 原文作者:Deven Joshi
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者: YueYong
- 校對者:HCMY
Flutter Challenges 是一項嘗試利用 Flutter 重新建立特定的應用程式UI或設計的挑戰。
此次挑戰將嘗試 Whatsapp Android 應用程式的主介面。請注意將重點放在 UI 上而不是實際獲取訊息。
開始
WhatsApp 的主介面包括:
- 一個帶有搜尋操作和選單的 AppBar
- 在 AppBar 的底部有四個標籤
- 一個用於拍照的相機標籤
- 一個用於多種用途的 FloatingActionButton
- 一個“聊天”標籤可檢視所有對話
- 一個“狀態”選項卡可檢視所有狀態
- 一個“打電話”選項卡可檢視所有的通話記錄
專案設定
讓我們建立一個名為 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,
),
複製程式碼
程式碼結果如下:
現在繼續
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"),
],
),
複製程式碼
現在,在轉到各個頁面之前,我們將新增選項卡所代表的頁面。用以下方法切換腳手架的現有“正文”程式碼:
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;
}
});
});
複製程式碼
繼續,
聊天介面
聊天螢幕有一個我們需要顯示的訊息列表。要建立訊息列表,我們使用 ListView.builder() 並構造我們的專案。
讓我們來看看聊天介面的列表項。
最外面的小部件是一行圖示和另一行
第二行內部是一列,包含一行和一個文字小部件。
該行具有標題和訊息日期。
讓我們構建一個聊天項模型作為用於儲存列表項詳細資訊的類。
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(),
],
);
},
複製程式碼
建立第一個列表後,結果如下:
我們可以類似地在其他螢幕上的螢幕上建立其他選項卡。完整的示例託管在GitHub上。
GitHub 連結 : github.com/deven98/Wha…
感謝您閱讀此 Flutter 挑戰。隨意提及您可能想要在 Flutter 中重新建立的任何應用程式。如果你喜歡它,一定要留下掌聲,再見。
不要忘了:The Medium App in Flutter
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。