[譯] 挑戰 Flutter 之 Twitter

MeFelixWang發表於2018-08-12

[譯] 挑戰 Flutter 之 Twitter

挑戰 Flutter 將嘗試在 Flutter 中重新建立特定應用的 UI 或設計。

此挑戰將嘗試實現安卓版 Twitter 的主頁。請注意,重點將放在 UI 上,而不是實際從後端伺服器獲取資料。

瞭解應用結構

[譯] 挑戰 Flutter 之 Twitter

Twitter 有四個由底部導航欄控制的主要頁面。

它們是:

  1. 主頁(展示訂閱的推文)
  2. 搜尋頁(搜尋人員,組織等)
  3. 通知頁(通知和提及)
  4. 訊息頁(私人訊息)

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 的樣子:

[譯] 挑戰 Flutter 之 Twitter

因為沒有應用中所需的圖示,所以我們將使用 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。

實現的底部導航欄:

[譯] 挑戰 Flutter 之 Twitter

構建頁面

讓我們構建四個基本頁面,這些頁面將在單擊相應的圖示時顯示。

建立的四個頁面(在不同的檔案中)如下:

使用者訂閱(主頁)頁面的程式碼如下:

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,),
    );
  }
}
複製程式碼

現在,我們將重新建立頁面。

建立使用者訂閱頁

[譯] 挑戰 Flutter 之 Twitter

頁面中有兩個元素: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,),
),
複製程式碼

我們將使用圖示而不是個人資料圖片。

[譯] 挑戰 Flutter 之 Twitter

重新建立的 AppBar

現在,我們需要建立推文列表。為此,我們使用 ListView.builder()。

來看看列表項。

[譯] 挑戰 Flutter 之 Twitter

首先,我們需要一個由 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 後,頁面如下:

[譯] 挑戰 Flutter 之 Twitter

重新建立的 Twitter 應用

這是重新構建的 Twitter 使用者訂閱頁。在 Flutter 中可以快速輕鬆地重新建立任何 UI,這說明了它的開發速度和可定製性非常不錯。兩者是很難兼顧的。

完整的示例託管在 Github 上。

Github 連結:github.com/deven98/Twi…

感謝閱讀此 Flutter 挑戰。可以留言告訴我任何你想要在 Flutter 中重新建立的應用。喜歡請給個 star,下次見。

不要錯過:

The Medium App in Flutter

WhatsApp in Flutter

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


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

相關文章