iOS使用Flutter_Boost管理頁(yè)面跳轉(zhuǎn)

上一篇文章介紹了如何集成Flutter_Boost,本篇將詳細(xì)介紹flutter如何與原生進(jìn)行交互。

首先給出文章demo,具體代碼可作參考。

一:flutter_module項(xiàng)目使用FlutterBoost進(jìn)行路由配置
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'simple_page_widgets.dart';

void main() {
  run App(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    FlutterBoost.singleton.registerPageBuilders({
      'first': (pageName, params, _) => FirstRouteWidget(),
      'second': (pageName, params, _) => SecondRouteWidget(),
      'flutterPage': (pageName, params, _) {
        print("flutterPage params:$params");
        return FlutterRouteWidget(params:params);
      },
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter example',
        builder: FlutterBoost.init(postPush: _onRoutePushed),
        home: Container());
  }

  void _onRoutePushed(
      String pageName, String uniqueId, Map params, Route route, Future _) {
  }
}

這里首先在Widget builder中初始化了FlutterBoost,然后在initState方法中通過(guò)FlutterBoost為三個(gè)頁(yè)面注冊(cè)了路由,這里注冊(cè)的路由是原生與flutter通用的,這個(gè)后面可以體現(xiàn)。

二:在Flutter頁(yè)面路由中使用FlutterBoost跳轉(zhuǎn)

總結(jié)在Flutter中有以下幾種跳轉(zhuǎn)方式:
1.Flutter=>Flutter(使用Flutter自己的路由)

Navigator.push(context, MaterialPageRoute(builder: (_) => FirstRouteWidget()));

以下三種跳轉(zhuǎn)方式,都是通過(guò)FlutterBoost進(jìn)行跳轉(zhuǎn),使用的是同一個(gè)方法,只是場(chǎng)景有所不同

FlutterBoost.singleton.open( String url,{Map<dynamic,dynamic> urlParams,Map<dynamic,dynamic> exts)

參數(shù)分別為:頁(yè)面名稱,通信傳參,擴(kuò)展參數(shù)。對(duì)應(yīng)相應(yīng)跳轉(zhuǎn)方式使用如下:
2.Flutter=>Flutter(使用原生的navigationController)
例:first頁(yè)面打開(kāi)路由名稱為second頁(yè)面,傳參為{"query": “aaa”},擴(kuò)展參數(shù)中可以添加一些特殊數(shù)據(jù),這里添加了{(lán)"animated": true},在原生中會(huì)解析為帶動(dòng)畫跳轉(zhuǎn)

FlutterBoost.singleton.open( "second",urlParams: {"query": "aaa"}, exts: {"animated": true})

3.Flutter=>原生(push)
例:first頁(yè)面打開(kāi)原生NativeViewController頁(yè)面,拼接native將在原生項(xiàng)目中解析為跳轉(zhuǎn)原生頁(yè)面,拼接push表明跳轉(zhuǎn)方式。

FlutterBoost.singleton.open( "native_push_NativeViewController",urlParams: {"query": "aaa"}, exts: {"animated": true})

4.Flutter=>原生(present)
同上,使用present跳轉(zhuǎn)方式。

FlutterBoost.singleton.open( "native_present_NativeViewController",urlParams: {"query": "aaa"}, exts: {"animated": true})

另外,F(xiàn)lutter關(guān)閉或返回上級(jí)頁(yè)面使用的是close方法,分為兩種
1.關(guān)閉當(dāng)前頁(yè)面

FlutterBoost.singleton.closeCurrent(result: {}, exts: {});

2.通過(guò)id關(guān)閉指定頁(yè)面

FlutterBoost.singleton.close('id', result: {}, exts: {});
三:原生項(xiàng)目中配置路由通信
import Foundation

//實(shí)現(xiàn)FLBPlatform協(xié)議方法,flutter項(xiàng)目和原生項(xiàng)目使用FlutterBoost進(jìn)行的跳轉(zhuǎn)都會(huì)通過(guò)該類進(jìn)行處理
class PlatformRouterImp: NSObject, FLBPlatform {
    //處理打開(kāi)原生頁(yè)面邏輯
    func openNative(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        var animated = false
        if exts["animated"] != nil{
            animated = exts["animated"] as! Bool
        }
        //與flutter端約定跳轉(zhuǎn)原生的url為三段式結(jié)構(gòu)native_method_name
        let urlArr = url.components(separatedBy: "_")
        if urlArr.count == 3 {
            //通過(guò)類名找到相應(yīng)頁(yè)面
            let cls : AnyClass? = NSClassFromString("TestWithFlutter." + urlArr[2])
            //該項(xiàng)目中的vc都繼承于BaseViewController,加了一個(gè)params用來(lái)接收Flutter傳過(guò)來(lái)的參數(shù),另有方案的話改為UIViewController即可。
            if let clsType = cls as? BaseViewController.Type {
                let targetVC = clsType.init()
                targetVC.params = urlParams
                if urlArr[1] == "push" {
                    self.navigationController().pushViewController(targetVC, animated: animated)
                    completion(true)
                } else if urlArr[1] == "present" {
                    let navVC = UINavigationController(rootViewController: targetVC)
                    self.navigationController().present(navVC, animated: animated) {
                        completion(true)
                    }
                }
            }
        }
    }
    //FlutterBoost的open方法會(huì)在這里進(jìn)行處理
    func open(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        if url.prefix(6) == "native" {//約定前面字符為native時(shí)跳轉(zhuǎn)原生頁(yè)面
            openNative(url, urlParams: urlParams, exts: exts, completion: completion)
        } else {//否則打開(kāi)Flutter頁(yè)面
            var animated = false
            if exts["animated"] != nil{
                animated = exts["animated"] as! Bool
            }
            let vc = FLBFlutterViewContainer.init()
            vc.setName(url, params: urlParams)
            self.navigationController().pushViewController(vc, animated: animated)
            completion(true)
        }
    }
    //FlutterBoost的present方法會(huì)在這里進(jìn)行處理,F(xiàn)lutter項(xiàng)目中不分present打開(kāi)方式,都會(huì)走open方法
    func present(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        //直接present出的navVC,會(huì)導(dǎo)致flutter路由中uniqueid混亂,有待研究
//        var animated = false
//        if exts["animated"] != nil{
//            animated = exts["animated"] as! Bool
//        }
        let vc = FLBFlutterViewContainer.init()
        vc.setName(url, params: urlParams)
        let navVC = UINavigationController(rootViewController: vc)
        navVC.modalPresentationStyle = .fullScreen
        let delegate = UIApplication.shared.delegate as! AppDelegate
        delegate.window?.rootViewController = navVC
//        navigationController().present(navVC, animated: animated) {
//            completion(true)
//        }
    }
    //FlutterBoost的close方法會(huì)在這里進(jìn)行處理
    func close(_ uid: String, result: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
        var animated = false;
        if exts["animated"] != nil{
            animated = exts["animated"] as! Bool
        }
        let presentedVC = self.navigationController().presentedViewController
        let vc = presentedVC as? FLBFlutterViewContainer
        if vc?.uniqueIDString() == uid {
            vc?.dismiss(animated: animated, completion: {
                completion(true)
            })
        }else{
            self.navigationController().popViewController(animated: animated)
        }
    }
    //獲取應(yīng)用的navigationController,用來(lái)進(jìn)行跳轉(zhuǎn)
    func navigationController() -> UINavigationController {
        let delegate = UIApplication.shared.delegate as! AppDelegate
        let navigationController = delegate.window?.rootViewController as! UINavigationController
        return navigationController
    }
}
四:在AppDelegate中初始化FlutterBoost
import UIKit
import Flutter

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
    
    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        let router = PlatformRouterImp.init();
        FlutterBoostPlugin.sharedInstance().startFlutter(with: router, onStart: { (engine) in
        });
        
        self.window = UIWindow.init(frame: UIScreen.main.bounds)
        let viewController = ViewController.init()
        let navi = UINavigationController.init(rootViewController: viewController)
        self.window.rootViewController = navi
        self.window.makeKeyAndVisible()
        
        return true
    }
    
}
五:原生使用FlutterBoost進(jìn)行跳轉(zhuǎn)

例:原生跳轉(zhuǎn)Flutter路由名為flutterPage的頁(yè)面

        FlutterBoostPlugin.open("flutterPage", urlParams:["query":"aaa"], exts: ["animated":true], onPageFinished: { (_ result:Any?) in
            print(String(format:"call me when page finished, and your result is:%@", result as! CVarArg));
        }) { (f:Bool) in
            print(String(format:"page is opened"));
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,697評(píng)論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,098評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,855評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,254評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,473評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,833評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,016評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,273評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,680評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 35,946評(píng)論 1 288
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,730評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,006評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容