Flutter學習之十 Scaffold

今日應做的事沒有做,明天再早也是耽誤了。

前言

不知道你們是怎么想的,我在學習新的語言開發(fā)UI的時候,都會和自己最熟悉的語言做比較。想對應iOS的UITabbarController(底部導航)是哪個?UINavigationController(導航控制器)是哪個?UIViewController(視圖控制器)是哪個?從去年的U3D到現(xiàn)在的Flutter,我剛開始接觸的時候都這么想的。U3D的暫且不談,在Flutter中,有一個組件和上面三者都有關系,那就是Scaffold(頁面骨架)。

正文

一個完整的路由頁可能會包含導航欄、抽屜菜單(Drawer)以及底部 Tab 導航菜單等。如果每個路由頁面都需要開發(fā)者自己手動去實現(xiàn)這些,這會是一件非常麻煩且無聊的事。幸運的是,Flutter Material 組件庫提供了一些現(xiàn)成的組件來減少我們的開發(fā)任務。Scaffold 是一個路由頁的骨架,我們使用它可以很容易地拼裝出一個完整的頁面。

構造函數(shù)

Scaffold({
  Key? key,
  this.appBar,
  this.body,
  this.floatingActionButton,
  this.floatingActionButtonLocation,
  this.floatingActionButtonAnimator,
  this.persistentFooterButtons,
  this.drawer,
  this.onDrawerChanged,
  this.endDrawer,
  this.onEndDrawerChanged,
  this.bottomNavigationBar,
  this.bottomSheet,
  this.backgroundColor,
  ...
  /// 省略部分
})
  • appBar:是一個Material風格的導航欄,通過它可以設置導航欄標題、導航欄菜單、導航欄底部的Tab標題等。
  • body:頁面主要內容。
  • floating 開頭的是右下角懸浮按鈕,有些電商App內容比較多,一般喜歡在右下角加個按鈕,一鍵回到頂部。
  • drawer 相關的,是抽屜效果。
  • bottomNavigationBar:底部導航,對應原生UITabbarController。

舉個栗子

我們要實現(xiàn)一個App頁面,它包含:

  • 一個導航欄
  • 頁面
  • 底部導航

底部導航代碼:

class TabbarController extends StatefulWidget {
  const TabbarController({Key? key}) : super(key: key);
  @override
  State<TabbarController> createState() => _TabbarControllerState();
}

class _TabbarControllerState extends State<TabbarController> {
  int _selectedIndex = 0;
  List<Widget> pages = <Widget>[
    const HomePage(),
    const UIPage(),
    const AnimationPage(),
    const MePage(),
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _selectedIndex,
        children: pages,
        sizing: StackFit.expand,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: '首頁'),
          BottomNavigationBarItem(icon: Icon(Icons.view_agenda), label: 'UI'),
          BottomNavigationBarItem(icon: Icon(Icons.animation), label: '動畫'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
        ],
        currentIndex: _selectedIndex,
        fixedColor: Colors.blue,
        type: BottomNavigationBarType.fixed,
        onTap: _onItemTapped,
      ),
    );
  }

  _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
}

TabbarController用到了兩個組件,BottomNavigationBarIndexedStack。簡單介紹一下BottomNavigationBar,就是類似原生的UITabbarController。

BottomNavigationBar

  • items: 數(shù)組放是按鈕。
  • currentIndex: 當前選中。
  • fixedColor:選中的顏色,還有基礎顏色可自行查看構造方法。
  • onTap: 點擊事件。

IndexedStack就是里面的Widget是在堆疊的,給定指定下標就能顯示對應的Widget

IndexedStack:

  • children:視圖數(shù)組,里面存放堆疊的Widget。
  • index: 需要顯示的Widget下標

BottomNavigationBarIndexedStack兩者結合就能實現(xiàn)底部導航切換效果,效果如下:

TabbarController.gif

再看下首頁(HomePage())的代碼:

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return HomePageState();
  }
}

//state 控制widget的改變
class HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('首頁'),
      ),
      body: ListView(
        children: [
          Image.asset(
            'images/top.jpeg',
            height: 240,
            fit: BoxFit.cover,
          ),
          titleSection,
          buttonSection,
          textSection,
        ],
      ),
    );
  }
  /// 省略 titleSection、 buttonSection、textSection的實現(xiàn)
}

可以看到,首頁用到了組件AppBar,廢話不多說,先看看構造函數(shù):

AppBar({
  Key? key,
  this.leading, //導航欄最左側Widget,常見為抽屜菜單按鈕或返回按鈕。
  this.automaticallyImplyLeading = true, //如果leading為null,是否自動實現(xiàn)默認的leading按鈕
  this.title,// 頁面標題
  this.actions, // 導航欄右側菜單
  this.bottom, // 導航欄底部菜單,通常為Tab按鈕組
  this.elevation = 4.0, // 導航欄陰影
  this.centerTitle, //標題是否居中 
  this.backgroundColor,
  ...   //其他屬性見源碼注釋
})

注釋已經(jīng)寫好,也是很簡單,常用的就左右兩側的按鈕,leading是左側按鈕,actions是右側的,是個數(shù)組,便于實現(xiàn)右側多按鈕頁面。

總結

通過上面的對Scaffold的使用,可以得出以下結論:

  • Scaffold只用AppBarbody兩個屬性,那么該Widget就相當于原生有的導航欄UIViewController。
  • Scaffold用到BottomNavigationBar,那個該Widget就相當于原生的UITabbarController。
有興趣的小伙伴可以看下我的 Flutter學習記錄

后記

Scaffold對于我這開始是iOS原生開發(fā)的程序猿來說,還是一個比較牛皮的組件,幾個簡單的屬性(抽屜、懸浮按鈕還沒提呢)賦值就能實現(xiàn)對于原生來說比較復雜的頁面,快,太快了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容