Flutter入門(mén)(21):Flutter 組件之路由表封裝思路詳解

1. 基本介紹

這里本應(yīng)該繼續(xù)更新組件詳解的,但是無(wú)奈 flutter 組件太多,導(dǎo)致講解的工程顯得非常累贅。作為一個(gè)老碼農(nóng)了,有一點(diǎn)代碼潔癖,這一點(diǎn)肯定是不能容忍的。這里對(duì)路由表進(jìn)行封裝,這里不一定是最好的封裝方式,只是按著我自己的代碼習(xí)慣來(lái)進(jìn)行了一個(gè)整理。后續(xù)如果有好的封裝方式,會(huì)再次更新。

2. 示例代碼

代碼下載地址。如果對(duì)你有幫助的話記得給個(gè)關(guān)注,代碼會(huì)根據(jù)我的 Flutter 專題不斷更新。

3. 為什么要進(jìn)行封裝?

  • 文件過(guò)多,手動(dòng)跳轉(zhuǎn)代碼太復(fù)雜

我這里最開(kāi)始創(chuàng)建工程時(shí)并沒(méi)有使用路由,使用 if else 對(duì)點(diǎn)擊事件進(jìn)行攔截,手動(dòng)跳轉(zhuǎn)到各個(gè)頁(yè)面。剛開(kāi)始頁(yè)面較少,其實(shí)沒(méi)有太大影響,也很直觀方便。隨著工程文件越來(lái)越多,if else 越來(lái)越多,這樣的代碼質(zhì)量就肯定會(huì)被拉低。

  • main.dart 文件引用以及邏輯代碼不清晰

main.dart 文件作為代碼入口,邏輯不清晰,代碼冗余沒(méi)有封裝,是一件很沒(méi)有排面的事情,有著代碼潔癖的同學(xué)肯定也是不能容忍。如果把路由表不做封裝,直接放在 main.dart 里,輕則幾百行,多則上千行的引用,看著肯定非常難受。

  • 不易管理

假設(shè)我們?cè)?main.dart 里手動(dòng)添加了路由,以后每次創(chuàng)建新的頁(yè)面,都需要來(lái)創(chuàng)建和引用。維護(hù)起來(lái)是一件非常頭疼的事情,并且容易遺漏。

4. 封裝思路

4.1 文件管理

首先我們先獨(dú)立出來(lái)一個(gè)文件,創(chuàng)建相關(guān)的管理類。創(chuàng)建數(shù)據(jù)源,為自定義路由,以及未知路由提供 MaterialPageRoute,這樣 main.dart 只需要調(diào)用管理類的方法,為攔截路由以及未知路由提供數(shù)據(jù)。

import 'package:flutter/material.dart';
import 'package:FMStudyApp/FMRouteManager.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    FMRouteManager manager = FMRouteManager();
    return MaterialApp(
      title: 'Flutter Demo',
      initialRoute: '/',
      onGenerateRoute: (setting){
        return manager.routeWithSetting(setting);
      },
      onUnknownRoute: (setting){
        return manager.unknowRouteWithSetting(setting);
      },
    );
  }
}
import 'package:FMStudyApp/home/home.dart';
import 'package:flutter/material.dart';

class FMRouteManager {
  // 路由總表
  Map <String, WidgetBuilder> _routeMap = {};

  // 自定義路由
  MaterialPageRoute routeWithSetting(RouteSettings setting){
    WidgetBuilder builder = _routeMap[setting.name];
    if(builder != null) {
      return MaterialPageRoute(builder: builder);
    }
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 未知路由
  MaterialPageRoute unknowRouteWithSetting(RouteSettings setting){
    return MaterialPageRoute(builder: (context) => Scaffold());
  }
}

4.2 數(shù)據(jù)源管理

有了獨(dú)立的文件以及路由總表后,我們需要做的僅僅是按照業(yè)務(wù)分類,獨(dú)立創(chuàng)建對(duì)應(yīng)路由。我們按照不同頁(yè)面創(chuàng)建不同的子路由表,然后總表對(duì)子路由表進(jìn)行匯總,這樣就可以把不同業(yè)務(wù)拆分開(kāi)。易于管理,易于維護(hù),易于查找。

import 'package:FMStudyApp/Widgets/Material_components/appbar.dart';
import 'package:FMStudyApp/home/home.dart';
import 'package:flutter/material.dart';

class FMRouteManager {
  // 路由總表
  Map <String, WidgetBuilder> _routeMap = {};

  FMRouteManager(){
    _routeMap.addAll(mapForHome());
    _routeMap.addAll(mapForMaterialComponents());
  }

  // 自定義路由
  MaterialPageRoute routeWithSetting(RouteSettings setting){
    WidgetBuilder builder = _routeMap[setting.name];
    if(builder != null) {
      return MaterialPageRoute(builder: builder);
    }
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 未知路由
  MaterialPageRoute unknowRouteWithSetting(RouteSettings setting){
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 首頁(yè)表
  Map <String, WidgetBuilder> mapForHome(){
    return {
      "/": (BuildContext context) => FMHomeVC(),
    };
  }

  // MaterialComponents 表
  Map <String, WidgetBuilder> mapForMaterialComponents(){
    return {
      "/MaterialComponents/AppBar": (BuildContext context) => FMAppBarVC(),
    };
  }
}

4.3 攔截路由處理

我們這里對(duì)攔截路由可以進(jìn)行處理,例如判斷用戶未登錄,或者其他情況,我們統(tǒng)一處理。

import 'package:FMStudyApp/Widgets/Material_components/appbar.dart';
import 'package:FMStudyApp/home/home.dart';
import 'package:flutter/material.dart';

class FMRouteManager {
  // 路由總表
  Map <String, WidgetBuilder> _routeMap = {};
  // 攔截參數(shù),用來(lái)攔截路由表,進(jìn)行不同操作
  final _isLogin = true;
  final _otherJudge = true;

  FMRouteManager(){
    _routeMap.addAll(mapForHome());
    _routeMap.addAll(mapForMaterialComponents());
    print(_routeMap);
  }

  // 自定義路由
  MaterialPageRoute routeWithSetting(RouteSettings setting){
    // 攔截未登錄路由
    if (!_isLogin) {
      return loginRoute(setting);
    }
    // 攔截其他情況路由
    if (!_otherJudge) {
      return ohterRoute(setting);
    }

    WidgetBuilder builder = _routeMap[setting.name];
    if(builder != null) {
      return MaterialPageRoute(builder: builder);
    }
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 未知路由
  MaterialPageRoute unknowRouteWithSetting(RouteSettings setting){
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 登錄路由
  MaterialPageRoute loginRoute(RouteSettings setting){
    // 這里可以替換為自定義的 Login 頁(yè)面
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 攔截其他情況路由
  MaterialPageRoute ohterRoute(RouteSettings setting){
    // 這里可以替換為自定義的 Login 頁(yè)面
    return MaterialPageRoute(builder: (context) => Scaffold());
  }

  // 首頁(yè)表
  Map <String, WidgetBuilder> mapForHome(){
    return {
      "/": (BuildContext context) => FMHomeVC(),
    };
  }

  // MaterialComponents 表
  Map <String, WidgetBuilder> mapForMaterialComponents(){
    return {
      "/MaterialComponents/AppBar": (BuildContext context) => FMAppBarVC(),
    };
  }
}

5. 技術(shù)小結(jié)

封裝其實(shí)只是一個(gè)思路,沒(méi)有最好或者最差,思想很明確,讓復(fù)雜的代碼簡(jiǎn)單化,使雜亂的代碼序列化。經(jīng)過(guò)這樣處理,我們將路由放在了一個(gè)單獨(dú)的管理類進(jìn)行管理和操作。同理,如果業(yè)務(wù)特別復(fù)雜,我們依舊可以對(duì)不同業(yè)務(wù)單獨(dú)創(chuàng)建文件來(lái)做路由表,然后使用總表對(duì)所有路由表進(jìn)行匯總。
總之,沒(méi)有最好的,只有最適合的。

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

友情鏈接更多精彩內(nèi)容