Flutter的SPA實戰,路由攔截器,全局Toast Loading

全局Toast/Loading問題

在Flutter開發中,全局的Toast/Loading很狗血,實現已有的實現方法都不是很人性化。最近在Dio做請求攔截器的時候Overlay一直獲取不到context,每個頁面進入都存一遍很不方便,如果在MaterialApp中存context,那麼調用Navigator.of(context).pushReplacementNamedremoveUtils的操作時都會報錯。

全局自定義命名路由動畫問題

除了以上坑點。在使用命名路由的時候動畫Flutter也沒提供修改方法。Navigator.pushNamed(context, "/login");如果是android那麼動畫就是從下而上,一點都不fashion。

頁面路由攔截器問題

Flutter的路由很特殊,如果想實現一個Router鉤子要怎麼辦呢? - -!我就是樣攔截路由,無論是埋點或者是以前其他特殊功能。都需要一個統一的路由調度。

解決思路

爲了解決上面的Flutter坑點,聯繫Web端非常流行的SPA應用,如果我們的頁面一直是單頁那麼context就是全局的。而且可以實現頁面的攔截器。非常nice

SPA 單頁面應用解決方案

直接上代碼,首先實現一個單頁的頁面管理器。 so easy...

    MaterialApp(
        home: ManagerPage(),
        // ...
      )

然後是頁面管理器ManagerPage的實現,利用Flutter自帶的Navigator,不熟悉的童鞋可以看看我以前寫的關於Navigator的文章。

    Widget build(BuildContext context) {
        // 利用 EventBus 來調度
        eventBus.on('showToast', (message) {
            Toast.show(context, message);
        });
        
        return Navigator( // 實現SPA
          initialRoute: '/',
          onGenerateRoute: (RouteSettings settings) {
    
            // 路由表對應單頁
            Widget _page = ZRouter.routerStore[settings.name];
            
            // 埋點等操作
            
            // 自定義路由動畫
            return CupertinoPageRoute(
              settings: settings,
              builder: (context) => _page
            );
          }
        );
    }

關於routerStore,一個SPA路由表

    static Map<String, Widget> get routerStore => {
        '/': SplashPage(),
        '/main_page': NavPage(),
        '/login': LoginPage(),
        '/product_detail': ProductDetailsPage()
      };

在子頁面使用

    // 直接通過 Navigator.pushNamed 命名路由和傳參。
    Navigator.pushNamed(context, "/login", arguments: RouteArguments<String>('想從活動登陸'));
    
    // 使用全局toast
    eventBus.emit('showToast', '系統繁忙請稍後再試...');

對請求攔截器的適配

    onResponse: (Response response) {
      // 在返回響應數據之前做一些預處理
      if (response.data['code'] != '000') {
        eventBus.emit('showToast', '系統繁忙請稍後再試...');
      }
      return response;
    },
    onError: (DioError error) {
      // 當請求失敗時做一些預處理
      eventBus.emit('showToast', '程序員GG正在想問題...');
      return error;
    }

源碼 https://github.com/zhongmeizhi/fultter-example-app

覺得有用 star 一下哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章