欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter 構(gòu)建一個常用的頁面框架

 更新時間:2021年05月19日 11:35:59   作者:島上碼農(nóng)  
大多數(shù) App 中都會有底部導(dǎo)航欄,通過底部導(dǎo)航欄切換實(shí)現(xiàn)不同頁面之間的切換。在Flutter 中提供了 BottomNavigationBar組件實(shí)現(xiàn)底部導(dǎo)航。本篇介紹通過 BottomNavigationBar和 IndexedStack構(gòu)建最為常見的 App 頁面框架。

最終實(shí)現(xiàn)的結(jié)果如上圖所示,頂部共用一個導(dǎo)航欄,底部有四個圖標(biāo)導(dǎo)航,點(diǎn)擊對應(yīng)的圖標(biāo)跳轉(zhuǎn)到對應(yīng)的頁面。

圖標(biāo)準(zhǔn)備

本次例程需要4個圖標(biāo),2種顏色,可以從 iconfont 中找到自己需要的圖標(biāo)下載不同的顏色使用。然后在 pubspec.yaml 中的 assets 指定素材所在目錄。需要注意的是如果是 png 文件直接指定整個目錄即可,但如果是 jpg 格式,則需要同時指定文件名及后綴。

BottomNavigationBar 簡介

BottomNavigationBar的構(gòu)造函數(shù)如下:

BottomNavigationBar({
    Key? key,
    required this.items,
    this.onTap,
    this.currentIndex = 0,
    this.elevation,
    this.type,
    Color? fixedColor,
    this.backgroundColor,
    this.iconSize = 24.0,
    Color? selectedItemColor,
    this.unselectedItemColor,
    this.selectedIconTheme,
    this.unselectedIconTheme,
    this.selectedFontSize = 14.0,
    this.unselectedFontSize = 12.0,
    this.selectedLabelStyle,
    this.unselectedLabelStyle,
    this.showSelectedLabels,
    this.showUnselectedLabels,
    this.mouseCursor,
  })

其中常用的屬性為:

  • items:及對應(yīng)的頁面組件數(shù)組
  • currentIndex:默認(rèn)顯示第幾個頁面
  • type:組件類型,使用BottomNavigationBarType枚舉,有 fixed 和 shifting 兩種。fixed 是圖標(biāo)固定位置,而 shifting 的圖標(biāo)點(diǎn)擊后會有一個漂移效果,可以實(shí)際試一下,一般用fixed 比較多。
  • onTap:點(diǎn)擊后的事件,一般用這個更新狀態(tài)數(shù)據(jù),以便更新頁面。

其他屬性用于控制樣式的,可以根據(jù)實(shí)際需要設(shè)置圖標(biāo)大小,主題色,字體等參數(shù)。

構(gòu)建項(xiàng)目頁面結(jié)構(gòu)

首先,新建四個業(yè)務(wù)頁面,分別是 dynamic.dart,message.dart,category.dart 和 mine.dart,分別對應(yīng)動態(tài)、消息、分類瀏覽和個人中心四個頁面。目前這四個頁面很簡單,只是在頁面中間依次顯示“島上碼農(nóng)”四個字。代碼都是類似的,以 dynamic 為例:

import 'package:flutter/material.dart';

class DynamicPage extends StatelessWidget {
  const DynamicPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('島'),
      ),
    );
  }
}

注意的是這里的 Scaffold 沒有 AppBar 了,這是因?yàn)樵谑醉撘呀?jīng)有了,如果再有 AppBar 就會出現(xiàn)兩個。

其次,新建首頁,用于管理四個業(yè)務(wù)頁面,命名為 app.dart。app.dart 使用了 BottomNavigationBar 管理四個業(yè)務(wù)頁面的切換。

import 'package:flutter/material.dart';
import 'dynamic.dart';
import 'message.dart';
import 'category.dart';
import 'mine.dart';

class AppHomePage extends StatefulWidget {
  AppHomePage({Key key}) : super(key: key);

  @override
  _AppHomePageState createState() => _AppHomePageState();
}

class _AppHomePageState extends State<AppHomePage> {
  int _index = 0;

  List<Widget> _homeWidgets = [
    DynamicPage(),
    MessagePage(),
    CategoryPage(),
    MinePage(),
  ];

  void _onBottomNagigationBarTapped(index) {
    setState(() {
      _index = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('島上碼農(nóng)'),
      ),
      body: IndexedStack(
        index: _index,
        children: _homeWidgets,
      ),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        currentIndex: _index,
        onTap: _onBottomNagigationBarTapped,
        items: [
          _getBottomNavItem(
              '動態(tài)', 'images/dynamic.png', 'images/dynamic-hover.png', 0),
          _getBottomNavItem(
              ' 消息', 'images/message.png', 'images/message-hover.png', 1),
          _getBottomNavItem(
              '分類瀏覽', 'images/category.png', 'images/category-hover.png', 2),
          _getBottomNavItem(
              '個人中心', 'images/mine.png', 'images/mine-hover.png', 3),
        ],
      ),
    );
  }

  BottomNavigationBarItem _getBottomNavItem(
      String title, String normalIcon, String pressedIcon, int index) {
    return BottomNavigationBarItem(
      icon: _index == index
          ? Image.asset(
              pressedIcon,
              width: 32,
              height: 28,
            )
          : Image.asset(
              normalIcon,
              width: 32,
              height: 28,
            ),
      label: title,
    );
  }
}

這里關(guān)鍵的地方有兩個,一是使用的 IndexedStack,這是一個管理頁面顯示層級的容器。使用 index 屬性確定當(dāng)前容器里那個頁面在最頂上,容器里的頁面通過 children 屬性設(shè)置,要求是一個 Widget 數(shù)組。因此,邏輯就是當(dāng) BottomNavigationBar 中的圖標(biāo)被點(diǎn)擊后,對應(yīng)點(diǎn)擊事件會回調(diào) onTap屬性指定的方法,將當(dāng)前的點(diǎn)擊索引值傳遞回調(diào)函數(shù),因此可以利用這個方式控制 IndexedStack 的頁面層級切換。

最后,使用了狀態(tài)變量_index 存儲IndexedStatck當(dāng)前顯示頁面的索引值,然后當(dāng) BottomNavigationBar的圖標(biāo)點(diǎn)擊事件發(fā)生后,在回調(diào)函數(shù)中使用 setState 更新狀態(tài)變量_index 來刷新當(dāng)前界面。

簡化入口

main.dart 是入口文件,應(yīng)當(dāng)做最基礎(chǔ)的配置和全局初始化配置,而不應(yīng)該有業(yè)務(wù)代碼,因此可以簡化為從main 方法加載首頁即可。通過這種方式可以讓 main.dart 文件即為簡潔。這也是在開發(fā)的時候需要注意的地方,將不相關(guān)的代碼剝離,相關(guān)的代碼聚合,即所謂的“高內(nèi)聚,低耦合”原則。

import 'package:flutter/material.dart';
import 'app.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App 框架',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AppHomePage(),
    );
  }
}

代碼復(fù)用

寫代碼的時候要注意復(fù)用,在這里將構(gòu)建 BottomNavigationBar 元素抽離出了一個構(gòu)建方法_getBottomNavItem,從而提高代碼的復(fù)用性和維護(hù)性,也可以避免 Flutter 的組件構(gòu)建的 build 方法中出現(xiàn)過多的元素和嵌套,影響代碼的可讀性。

以上就是Flutter 構(gòu)建一個常用的頁面框架的詳細(xì)內(nèi)容,更多關(guān)于Flutter 構(gòu)建頁面框架的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論