[譯] 如何用 Flutter 來建立一個帶有底部導航欄的應用程序

若是你從事移動開發,你可能據說過谷歌的跨平臺 SDK:Flutter。Flutter 的 beta 版本 於 2 月 27 日發佈,並於近期發佈了第一個預覽版。爲了幫助您開始使用 Flutter,本教程將介紹 SDK 的一些基本內容,同時還將介紹如何設置底部導航欄。爲了幫助您學習,本教程的代碼能夠在 GitHub上得到。前端

什麼是 Flutter?

在咱們開始編寫代碼以前,讓咱們先談談什麼是 Flutter。Flutter SDK 繼承了一套完整的開發框架,包括在 Android 和 iOS 上構建原生移動應用所需的 widget 和工具。與其餘諸如 React Native 和 Xamarin 等跨平臺框架的區別在於,它不使用平臺原生 widget,也不使用 webview。相反,Flutter 有本身的用 C/C++ 編寫的渲染引擎,而用來編寫 Flutter 應用程序的 Dart 代碼在各個平臺上均可以編譯成底層代碼。這就能夠在每一個平臺上都能作出高性能的應用。不只應用在使用體驗上很是快,並且經過 Flutter 的熱重載特性也大大加快了開發時間。熱重載容許開發人員在他們的設備或模擬器上當即顯示修改內容的變化效果,由此能夠減小那些浪費在等待代碼編譯的時間。android

如何建立一個 Flutter 應用

如今咱們已經瞭解了 Flutter 是什麼,讓咱們開始建立咱們的應用程序。若是您尚未準備好開發環境,請按照 Flutter 網站的步驟安裝 Flutter SDK。要建立應用程序,請運行「flutter create my_app」。若是您想讓您的應用程序使用 Swift 或 Kotlin 做爲平臺特定代碼,那麼您能夠從終端或命令行運行「flutter create -i Swift -a Kotlin my_app」。打開你建立的新項目,你可使用安裝了 Dart 插件的 VS Code 或者安裝了 Flutter 和 Dart 插件的 Android Studio。若是您須要編輯器安裝的相關幫助,請參考 Flutter 的 幫助文檔ios

第一步 定義入口點

讓咱們從打開 main.dart 文件開始,該文件位於 lib/ 目錄下。接下來,因爲咱們要從頭開始編寫應用程序,因此刪除文件中的全部代碼。這個文件是咱們應用程序的入口點。在文件的開始編寫:git

import 'package:flutter/material.dart';
複製代碼

這就導入了 Flutter SDK 提供的 Material Design widgets。若是您想查看全部提供的 widget,能夠在 Widget 目錄 中查看。github

在導入語句以後,咱們須要添加 main 方法。web

void main() => runApp(App());
複製代碼

若是您在添加 main 方法後看到一些錯誤,不要擔憂。這是由於咱們尚未建立傳遞給 runApp 函數的 App widget 類。runApp 函數接收一個類型爲 Widget 的類,並將它做爲 root widget 運行。後端

如今咱們要建立咱們的 App widget。仍是在 main.dart 裏面,在 main 方法下面添加如下的代碼。bash

class App extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'My Flutter App',
     home: Home(),
   );
 }
}
複製代碼

這就建立了一個新的無狀態 widget App。之因此是一個無狀態 widget,由於它的構建方法中沒有任何內容會依賴於狀態更新。全部的 StatelessWidgets 都須要實現 build 方法,由於這是咱們建立用戶界面的地方。在咱們的 App widget 中,咱們簡單地建立了一個新的 MaterialApp,並將 Home 屬性設置爲咱們但願顯示的第一個頁面或 widget。在本例中,咱們把它設置爲 Home widget,咱們將在接下來建立這個 widget。app

第二步 建立主頁

lib 目錄下,建立一個新文件,並將其命名爲 home_widget.dart。在這個文件的頭部,咱們須要再次導入 material widgets。框架

import 'package:flutter/material.dart';
複製代碼

接下來,咱們將建立做爲咱們主頁的 widget。爲此,咱們將建立一個新的 StatefulWidget。當用戶界面須要根據應用程序的當前狀態發生變化時,StatefulWidget 就派上用場了。例如,如今咱們要使用底部導航欄,咱們的 Home widget 將根據當前選定的選項卡來渲染出不一樣的 widget。首先,在導入語句下面添加如下代碼。

class Home extends StatefulWidget {
 @override
 State<StatefulWidget> createState() {
    return _HomeState();
  }
}
複製代碼

您可能會注意到,這個 widget 類沒有實現咱們前面提到的 build 方法。當涉及到 StatefulWidgets 時,build 方法會在 widget 對應的 State 類中實現。在 StatefulWidget 中,惟一須要的方法是咱們在上面實現的 createState 方法,咱們只返回一個 _HomeState 類實例。類名前面的 「_」 表明 Dart 將類或類屬性標記爲 private。咱們如今須要建立 home widget 的 state 類。在 home_widget.dart 文件的末尾添加這個段代碼:

class _HomeState extends State<Home> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text('My Flutter App'),
     ),
     bottomNavigationBar: BottomNavigationBar(
       currentIndex: 0, // this will be set when a new tab is tapped
       items: [
         BottomNavigationBarItem(
           icon: new Icon(Icons.home),
           title: new Text('Home'),
         ),
         BottomNavigationBarItem(
           icon: new Icon(Icons.mail),
           title: new Text('Messages'),
         ),
         BottomNavigationBarItem(
           icon: Icon(Icons.person),
           Title: Text('Profile')
         )
       ],
     ),
   );
 }
}
複製代碼

這裏有不少內容,咱們來逐一看看。在 _HomeState 類中,咱們實現了 Home widget 的 build 方法。咱們從 build 方法返回的 widget 叫作 Scaffold。這個 widget 有一些很棒的屬性,能夠幫助咱們佈置主屏幕,包括添加底部導航欄、滑動條和選項卡。咱們如今只使用它的 appBarbottomNavigationBar 屬性。在咱們的底部導航欄中,咱們返回一個列表,其中列出了咱們但願在底部欄中出現的項目。如您所見,咱們有三個選項卡,分別是 Home、Message 和 Profile。咱們還將當前索引做爲屬性設置爲 0。稍後咱們將把它與當前選項卡聯繫起來。當前索引可讓導航欄知道要將哪一個圖標用於當前選擇的選項卡。

此時,咱們差很少已經準備好第一次運行 Flutter 應用了,來看看咱們的成果。再回到 main.dart 文件,在頂部,咱們須要導入新建立的 Home widget。咱們能夠經過在當前的導入語句下添加下面這個導入語句來實現。

import 'home_widget.dart';
複製代碼

咱們如今應該能夠運行咱們的應用了。你能夠在 VS Code 裏面,任意的 Dart 文件裏按 F5,或者在 Android Studio 中點擊 run 按鈕,或者在終端中輸入 flutter run。若是您須要模擬器安裝或者模擬運行應用程序的相關幫助,請參考 Flutter 的幫助文檔。若是一切順利,你的應用應該是這樣的。

flutter1

太棒了!咱們如今已經有一個應用程序了,並且它有很漂亮的底部導航欄。然而,這裏有一個問題。咱們的導航欄不會導引到任何地方!如今讓咱們解決這個問題。

第三步 準備導航

回到 home_widget.dart 文件,咱們須要對 _HomeState 類作一些更改。在類的頂部,咱們須要添加兩個新的實例屬性。

class _HomeState extends State<Home> {
  int _currentIndex = 0;
  final List<Widget> _children = [];
...
複製代碼

第一個是當前所選選項卡的索引,另外一個則是選項卡對應的但願渲染的 widget 列表。

接下來,咱們須要使用這些屬性來告訴咱們的 widget,當一個新選項卡被選中時須要顯示什麼。爲此,咱們須要對 build 方法返回的 scaffold widget 進行一些更改。這是咱們新的 build 方法。

@override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text('My Flutter App'),
     ),
     body: _children[_currentIndex], // new
     bottomNavigationBar: BottomNavigationBar(
       onTap: onTabTapped, // new
       currentIndex: _currentIndex, // new
       items: [
         new BottomNavigationBarItem(
           icon: Icon(Icons.home),
           title: Text('Home'),
         ),
         new BottomNavigationBarItem(
           icon: Icon(Icons.mail),
           title: Text('Messages'),
         ),
         new BottomNavigationBarItem(
           icon: Icon(Icons.person),
           title: Text('Profile')
         )
       ],
     ),
   );
 }
複製代碼

咱們的 build 方法中更改的三行用 // new 註釋了。首先,咱們添加了 scaffold 的 body 屬性,即在應用程序欄和底部導航欄之間顯示的 widget。咱們將 body 設置爲與 _children widget 列表中相對應的 widget。接下來,咱們給底部導航欄添加 onTap 屬性。咱們將它設置爲一個名爲 ontabtap 的函數,該函數將接收被選中選項卡的索引並決定如何處理它。咱們立刻就實現這個函數。最後,咱們將底部導航欄的 currentIndex 設置爲 state 類裏面的 _currentIndex 屬性。

第四步 處理導航

如今,咱們將添加上一步中提到的 ontabtap 函數。在 _HomeState 類的底部添加如下函數。

void onTabTapped(int index) {
   setState(() {
     _currentIndex = index;
   });
 }
複製代碼

這個函數接收被選中選項卡的索引,並在咱們的 state 類上調用 setState。這將觸發 build 方法接收咱們傳遞給它的狀態信息並再次運行。在本例中,咱們將傳遞更新的選項卡索引,該索引將更改 scaffold widget 的 body,並激活導航欄上正確的選項卡。

第五步 添加子 widgets

咱們的應用程序就要完成了。最後一步是建立 _children widget 列表中用到的 widget 並把它們添加到導航欄。首先 在 lib 目錄下建立一個名爲 placeholder_widget.dart 的新文件。這個文件將做爲一個簡單的 StatelessWidget 來使用背景色。

import 'package:flutter/material.dart';

class PlaceholderWidget extends StatelessWidget {
 final Color color;

 PlaceholderWidget(this.color);

 @override
 Widget build(BuildContext context) {
   return Container(
     color: color,
   );
 }
}
複製代碼

如今咱們要作的就是嚮導航欄中添加 PlaceholderWidget。在 home_widget.dart 的頂部,須要導入咱們的 widget。

import 'placeholder_widget.dart';
複製代碼

而後,咱們要作的就是將這些 widget 添加到 _children 列表中,以便在選擇新選項卡時渲染它們。

class _HomeState extends State<Home> {
 int _currentIndex = 0;
 final List<Widget> _children = [
   PlaceholderWidget(Colors.white),
   PlaceholderWidget(Colors.deepOrange),
   PlaceholderWidget(Colors.green)
 ];
...
複製代碼

就是這樣!如今應該能夠運行應用程序並在選項卡之間切換了。若是您想要看到 Flutter 的熱重載特性,請嘗試更改一下 BottomNavigationBarItems。值得注意的是,更改傳遞給 PlaceholderWidgets 的顏色不會在熱重載期間反映出來,由於 Flutter 會保持咱們 StatefulWidget 的狀態。

image1

結論

在本教程中,咱們學習瞭如何搭建一個新的 Flutter 應用程序並讓底部導航欄工做。像 Flutter 這樣的跨平臺工具在移動領域愈來愈流行,由於它們縮短了開發時間。Flutter 有它的獨特之處,由於它不須要使用 底層原生的 widget 或 webview。目前採用 Flutter 的主要缺點之一是在功能特性上缺乏第三方支持。然而,Flutter 仍然是一種頗有前途的工具,使用它能夠在不犧牲性能的前提下編寫出很是棒的跨平臺應用程序。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


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

相關文章
相關標籤/搜索