- 原文地址:Flutter Challenge: Twitter
- 原文作者:Deven Joshi
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:MeFelixWang
挑戰 Flutter 將嘗試在 Flutter 中重新建立特定應用的 UI 或設計。
此挑戰將嘗試實現安卓版 Twitter 的主頁。請注意,重點將放在 UI 上,而不是實際從後端伺服器獲取資料。
瞭解應用結構
Twitter 有四個由底部導航欄控制的主要頁面。
它們是:
- 主頁(展示訂閱的推文)
- 搜尋頁(搜尋人員,組織等)
- 通知頁(通知和提及)
- 訊息頁(私人訊息)
BottomNavigationBar 有四個選項卡可以跳轉到每個頁面。
在我們的應用中將有四個不同的頁面,只需點選 BottomNavigationBar 上的專案來切換頁面。
建立專案
建立好 Flutter 專案(我將其命名為 twitter_ui_demo )後,清除專案中的預設程式碼,只留下這些:
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(
body: new Center(
),
);
}
}
複製程式碼
HomePage 中有一個 Scaffold,它存有我們的 BottomNavigationBar 以及當前啟用的頁面。
開始
因為底部導航欄是用於導航的主要元件,所以我們先試著實現它。
這是 BottomNavigationBar 的樣子:
因為沒有應用中所需的圖示,所以我們將使用 Font Flutter Awesome package 。在 pubspec.yaml 中新增依賴項並引入
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
複製程式碼
到檔案中。
BottomNavigationBar 的程式碼如下:
bottomNavigationBar: BottomNavigationBar(items: [
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.home, color: selectedPageIndex == 0? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.search, color: selectedPageIndex == 1? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.bell, color: selectedPageIndex == 2? Colors.blue : Colors.blueGrey,)
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.envelope, color: selectedPageIndex == 3? Colors.blue : Colors.blueGrey,),
),
], onTap: (index) {
setState(() {
selectedPageIndex = index;
});
}, currentIndex: selectedPageIndex)
複製程式碼
將其新增到 HomePage。
請注意,當設定圖示的顏色時,我們會檢查是否選中了圖示,然後指定顏色。在 Twitter 中,選中的圖示為藍色,讓我們將未選擇的圖示設定為 blueGrey。
定義一個名為 selectedPageIndex 的整型變數,用於儲存所選頁面的索引。在 onTap 函式中,我們將變數設定為新索引。用 setState() 包裹起來,因為我們需要重新整理頁面來重新渲染 AppBar。
實現的底部導航欄:
構建頁面
讓我們構建四個基本頁面,這些頁面將在單擊相應的圖示時顯示。
建立的四個頁面(在不同的檔案中)如下:
使用者訂閱(主頁)頁面的程式碼如下:
import 'package:flutter/material.dart';
class UserFeedPage extends StatefulWidget {
@override
_UserFeedPageState createState() => _UserFeedPageState();
}
class _UserFeedPageState extends State<UserFeedPage> {
@override
Widget build(BuildContext context) {
return Container();
}
}
複製程式碼
類似的,我們建立好搜尋,通知和訊息頁面。
回到基礎頁面中,引入這些頁面並定義成一個列表。
var pages = [
UserFeedPage(),
SearchPage(),
NotificationPage(),
MessagesPage(),
];
複製程式碼
在 Scaffold 中,寫入
body: pages[selectedPageIndex],
複製程式碼
它將設定 body 來展示這些頁面。
到目前為止,MyHomePage 基礎元件的程式碼如下:
class _MyHomePageState extends State<MyHomePage> {
var selectedPageIndex = 0;
var pages = [
UserFeedPage(),
SearchPage(),
NotificationPage(),
MessagesPage(),
];
@override
Widget build(BuildContext context) {
return new Scaffold(
body: pages[selectedPageIndex],
bottomNavigationBar: BottomNavigationBar(items: [
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.home, color: selectedPageIndex == 0? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.search, color: selectedPageIndex == 1? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.bell, color: selectedPageIndex == 2? Colors.blue : Colors.blueGrey,)
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.envelope, color: selectedPageIndex == 3? Colors.blue : Colors.blueGrey,),
),
], onTap: (index) {
setState(() {
selectedPageIndex = index;
});
}, currentIndex: selectedPageIndex,),
);
}
}
複製程式碼
現在,我們將重新建立頁面。
建立使用者訂閱頁
頁面中有兩個元素:AppBar 和推文列表。
首先製作 AppBar。它有一張使用者個人資料圖片和一個白底黑字的標題。
appBar: AppBar(
backgroundColor: Colors.white,
title: Text("Home", style: TextStyle(color: Colors.black),),
leading: Icon(Icons.account_circle, color: Colors.grey, size: 35.0,),
),
複製程式碼
我們將使用圖示而不是個人資料圖片。
重新建立的 AppBar
現在,我們需要建立推文列表。為此,我們使用 ListView.builder()。
來看看列表項。
首先,我們需要一個由 row 和 divider 組成的 column。
在 row 中,有一個 icon 和另一個 column。
該 column 中有一個用於展示推文資訊的 row,一個用於展示推文字身的 text,一個 image 和另一個用於對推文應用操作(如評論等)的 row。
為簡潔起見,我們暫時拋開 image,實際上和在 row 中新增 image 一樣簡單。
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.account_circle, size: 60.0, color: Colors.grey,),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Container(child: RichText(
text: TextSpan(
children: [
TextSpan(text:tweet.username, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, color: Colors.black),),
TextSpan(text:" " + tweet.twitterHandle,style: TextStyle(fontSize: 16.0, color: Colors.grey)),
TextSpan(text:" ${tweet.time}",style: TextStyle(fontSize: 16.0, color: Colors.grey))
]
),overflow: TextOverflow.ellipsis,
)),flex: 5,
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 4.0),
child: Icon(Icons.expand_more, color: Colors.grey,),
),flex: 1,
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(tweet.tweet, style: TextStyle(fontSize: 18.0),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Icon(FontAwesomeIcons.comment, color: Colors.grey,),
Icon(FontAwesomeIcons.retweet, color: Colors.grey,),
Icon(FontAwesomeIcons.heart, color: Colors.grey,),
Icon(FontAwesomeIcons.shareAlt, color: Colors.grey,),
],
),
)
],
),
)
],
),
),
Divider(),
],
);
複製程式碼
在建立一個用於提供簡單推文的幫助類和一個簡單的 FloatingActionButton 後,頁面如下:
重新建立的 Twitter 應用
這是重新構建的 Twitter 使用者訂閱頁。在 Flutter 中可以快速輕鬆地重新建立任何 UI,這說明了它的開發速度和可定製性非常不錯。兩者是很難兼顧的。
完整的示例託管在 Github 上。
Github 連結:github.com/deven98/Twi…
感謝閱讀此 Flutter 挑戰。可以留言告訴我任何你想要在 Flutter 中重新建立的應用。喜歡請給個 star,下次見。
不要錯過:
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。