最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter學習之創(chuàng)建一個內(nèi)嵌的navigation詳解

 更新時間:2023年03月13日 16:07:03   作者:flydean  
我們在flutter中可以使用Navigator.push或者Navigator.pushNamed方法來向Navigator中添加不同的頁面,從而達到頁面調(diào)整的目的。本文就來聊聊如何創(chuàng)建一個內(nèi)嵌的navigation吧

簡介

我們在flutter中可以使用Navigator.push或者Navigator.pushNamed方法來向Navigator中添加不同的頁面,從而達到頁面調(diào)整的目的。

一般情況下這樣已經(jīng)足夠了,但是有時候我們有多個Navigator的情況下,上面的使用方式就不夠用了。比如我們有一個主頁面app的Navigator,然后里面有一個匹配好友的功能,這個功能有多個頁面,因為匹配好友功能的多個頁面實際上是一個完整的流程,所以這些頁面需要被放在一個子Navigator中,并和主Navigator區(qū)分開。

那么應該如何處理呢?

搭建主Navigator

主Navigator是我們app的一些主要界面,這里我們有三個界面,分別是主home界面,一個setting配置界面和好友匹配界面。

其中好友匹配界面包含了三個子界面,這三個子界面將會用到子路由。

先來看下主路由,主路由的情況跟普通的路由沒啥區(qū)別,這里我們首先定義和home和setting匹配的兩個widget:HomePage和SettingsPage:

class HomePage extends StatelessWidget {
  const HomePage({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppBar(context),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24.0),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: const [
              SizedBox(
                width: 250,
                height: 250,
                child: Center(
                  child: Icon(
                    Icons.home,
                    size: 175,
                    color: Colors.blue,
                  ),
                ),
              ),
              SizedBox(height: 32),
              Text(
                '跳轉到好友匹配頁面',
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context).pushNamed(routeFriendMatch);
        },
        child: const Icon(Icons.add),
      ),
    );
  }

HomePage很簡單,它包含了一個floatingActionButton,當點擊它的時候會調(diào)用 Navigator.pushNamed方法進行路由切換。

然后是SettingsPage,它是一個簡單的Column:

class SettingsPage extends StatelessWidget {
  const SettingsPage({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppBar(),
      body: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: List.generate(8, (index) {
            return  ListTile(
              title: Text('設置項$index'),
            );
          }),
        ),
      ),
    );
  }

最后一個頁面是FriendMatchFlow,這個頁面比較復雜,我們在下一個再進行講解。

然后我們?yōu)橹髀酚稍趏nGenerateRoute方法中進行定義:

void main() {
  runApp(
    MaterialApp(
      onGenerateRoute: (settings) {
        late Widget page;
        if (settings.name == routeHome) {
          page = const HomePage();
        } else if (settings.name == routeSettings) {
          page = const SettingsPage();
        } else if (settings.name == routeFriendMatch) {
          page = const FriendMatchFlow(
            setupPageRoute: routeFriendMatchPage,
          );
        }

        return MaterialPageRoute<dynamic>(
          builder: (context) {
            return page;
          },
          settings: settings,
        );
      },
      debugShowCheckedModeBanner: false,
    ),
  );
}

主路由很簡單,跟普通的路由沒有太多的區(qū)別。

構建子路由

接下來是構建子路由的步驟。在主路由中,如果路由的名稱是routeFriendMatch,那么就會跳轉到FriendMatchFlow。

而這個flow頁面實際上是由幾個子頁面組成的:選擇好友頁面,等待頁面,匹配頁面和匹配完畢頁面。

具體的頁面代碼這里就不寫了,我們主要來講一下子路由的使用。

對于FriendMatchFlow來說,它本身是一個Navigator,所以我們的build方法是這樣的:

  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _isExitDesired,
      child: Scaffold(
        appBar: _buildFlowAppBar(),
        body: Navigator(
          key: _navigatorKey,
          initialRoute: widget.setupPageRoute,
          onGenerateRoute: _onGenerateRoute,
        ),
      ),
    );
  }

因為他需要根據(jù)用戶的不同點擊來進行內(nèi)部路由的切換,所以需要保存對當前子Navigator的應用,所以這里FriendMatchFlow是一個StatefulWidget,并且上面的_navigatorKey是一個GlobalKey對象,以提供對子Navigator的引用:

  final _navigatorKey = GlobalKey<NavigatorState>();

這里的_onGenerateRoute方法,跟主路由也是很類似的,主要定義的是子路由中頁面的跳轉:

  Route _onGenerateRoute(RouteSettings settings) {
    late Widget page;
    switch (settings.name) {
      case routeFriendMatchPage:
        page = WaitingPage(
          message: '匹配附近的好友...',
          onWaitComplete: _onDiscoveryComplete,
        );
        break;
      case routeFriendSelectPage:
        page = SelectFriendPage(
          onFriendSelected: _onFriendSelected,
        );
        break;
      case routeFriendConnectingPage:
        page = WaitingPage(
          message: '匹配中...',
          onWaitComplete: _onConnectionEstablished,
        );
        break;
      case routeFriendFinishedPage:
        page = FinishedPage(
          onFinishPressed: _exitSetup,
        );
        break;
    }

這里的on***Selected是VoidCallback回調(diào),用來進行路由的切換:

  void _onDiscoveryComplete() {
    _navigatorKey.currentState!.pushNamed(routeFriendSelectPage);
  }

  void _onFriendSelected(String deviceId) {
    _navigatorKey.currentState!.pushNamed(routeFriendConnectingPage);
  }

  void _onConnectionEstablished() {
    _navigatorKey.currentState!.pushNamed(routeFriendFinishedPage);
  }

可以看到上面的路由切換實際上是在子路由上切換,跟父路由無關。

如果想要直接從子路由跳出到父路由該怎么處理呢?很簡單,調(diào)用Navigator.of的pop方法即可:

  void _exitSetup() {
    Navigator.of(context).pop();
  }

這里的context默認是全局的context,所以會導致主路由的跳轉變化。

總結

以上的代碼運行結果如下:

雖然上面的例子看起來復雜,但是大家只要記住了不同的路由使用不同的Navigator范圍進行跳轉就行了。

到此這篇關于Flutter學習之創(chuàng)建一個內(nèi)嵌的navigation詳解的文章就介紹到這了,更多相關Flutter創(chuàng)建內(nèi)嵌navigation內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

高雄市| 黄陵县| 石屏县| 克什克腾旗| 霍山县| 类乌齐县| 九龙坡区| 连城县| 德清县| 海宁市| 诏安县| 陆川县| 元江| 惠东县| 杂多县| 丽水市| 东港市| 怀安县| 洮南市| 赤水市| 鄂托克旗| 明星| 济南市| 丰原市| 河北区| 九龙城区| 来凤县| 剑阁县| 凉山| 兖州市| 永胜县| 景泰县| 广水市| 庆阳市| 英吉沙县| 霍林郭勒市| 南澳县| 遂昌县| 额尔古纳市| 平远县| 泸西县|