1. 程式人生 > Android開發 >flutter混合(iOS)開發第一步使用(Flutter_Boost)完成頁面之間的跳轉傳值(一)

flutter混合(iOS)開發第一步使用(Flutter_Boost)完成頁面之間的跳轉傳值(一)

首先宣告我這裡使用的是Flutter_Boost

可以先去看看原始碼demo 簡單提一下原生混合Flutter我們主要做兩步,第一步在我們專案統計建立我們的Flutter_module 建立方式使用我們的終端執行

flutter create -t module (你要建立的Flutter專案名稱)
複製程式碼

這樣建立的方式就類似iOS中做cocopods外掛的方式,創建出來的專案使用AndroidStudio是能執行的完全沒有問題。 然後我的原生工程用我們的cocopods裡面有pods了,我們在podfile中去新增這樣的程式碼我把我的podfile貼出來,大家不用去那個配置那個Build Phases

裡面新增什麼run script。就我這樣就好了。那個Build Settings裡面的Enable Bitcode還是要改成NO這個不要忘記了。該說的都說完了,這就是iOS原生這邊需要配置的地方。

# Uncomment the next line to define a global platform for your project
# platform :ios,'9.0'

source 'https://github.com/CocoaPods/Specs.git'
# 新增模組所在路徑
flutter_application_path = '../JWellTruck_Flutter'
load File.join(flutter_application_path,'.ios'
,'Flutter','podhelper.rb') target 'JWellTruck' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for JWellTruck # 安裝Flutter模組 install_all_flutter_pods(flutter_application_path) target 'JWellTruckTests' do inherit! :search_paths # Pods for testing
end target 'JWellTruckUITests' do # Pods for testing end end 複製程式碼

搞完這些我們再去AppDelegate裡面配置我們的router

let router = PlatformRouterImp.init();
    FlutterBoostPlugin.sharedInstance().startFlutter(with: router,onStart: { (engine) in

        
});
複製程式碼

Flutter 混合開發頁面跳轉的幾種形式

nativeA -> flutterA -> flutterB -> nativeB -> flutterB

然後就是依次返回,這樣差不多就是一個App完整的頁面路由了。 這裡我使用的是Swift來做的混合開發,當然OC也是相同的道理。 首先第一步我們混合開發一般第一步是從原生到Flutter頁面。

最重要的一點必須說明一下,我們做的時候不管是Swift還是OC我們都要去寫一個繼承FLBPlatform的類,這裡主要是做頁面跳轉的重要地方,包括從Flutter傳過來的資料這些我們都可以在這裡拿到,這裡我貼一下我的這個類,只是拿官方demo稍微做了一點修改。主要是我自己的原生專案裡面的TabBarNavigation都是自定義的我的原生程式碼如下

import Foundation
import flutter_boost

class PlatformRouterImp: NSObject,FLBPlatform {
    func open(_ url: String,urlParams: [AnyHashable : Any],exts: [AnyHashable : Any],completion: @escaping (Bool) -> Void) {
        var animated = false;
        if exts["animated"] != nil{
            animated = exts["animated"] as! Bool;
        }
         let vc = FLBFlutterViewContainer.init()
            vc.setName(url,params: urlParams)
            vc.navigation.bar.isHidden = true
            vc.hidesBottomBarWhenPushed = true
            <!--這裡的topVC是我專案裡面寫的一個獲取最上層控制器的方法我也貼一下我的程式碼-->
            topVC?.navigationController!.pushViewController(vc,animated: animated);
        completion(true);
    }
    
    func present(_ url: String,completion: @escaping (Bool) -> Void) {
        var animated = false;
        if exts["animated"] != nil{
            animated = exts["animated"] as! Bool;
        }
        let vc = FLBFlutterViewContainer.init();
        vc.setName(url,params: urlParams);
        topVC?.navigationController!.present(vc,animated: animated) {
            completion(true);
        };
    }
    
    func close(_ uid: String,result: [AnyHashable : Any],completion: @escaping (Bool) -> Void) {
        var animated = false;
        if exts["backNative"] != nil{
            animated = exts["backNative"] as! Bool;
        }
        let presentedVC = topVC?.navigationController!.presentedViewController;
        let vc = presentedVC as? FLBFlutterViewContainer;
        if vc?.uniqueIDString() == uid {
            vc?.dismiss(animated: animated,completion: {
                completion(true);
            });
        }else{
            topVC?.navigationController!.popViewController(animated: animated);
        }
    }
    
//    func navigationController() -> UINavigationController {
//        let delegate = UIApplication.shared.keyWindow?.rootViewController as! UINavigationController
////        let navigationController = delegate.window?.rootViewController as! UINavigationController
//        return delegate.navigationController!
//    }
    
}
複製程式碼

我在我的公共類裡面寫了一個這樣的方法(程式碼裡面所有的屬性不會存在找不到情況了)

var topVC: UIViewController? {
    var resultVC: UIViewController?
    resultVC = _topVC(UIApplication.shared.keyWindow?.rootViewController)
    while resultVC?.presentedViewController != nil {
        resultVC = _topVC(resultVC?.presentedViewController)
    }
    return resultVC
}
複製程式碼

接下來我們把所有情況都分類都說一遍:

1、 Native To Flutter

Native裡面的程式碼:

 FlutterBoostPlugin.open("頁面引數名,就是Flutter裡面配置的這個名字,mian頁面需要配置的",urlParams: ["這裡是一個識別符號類似標記那種"],exts: ["這裡給一個引數,比如我們push的時候animated是否需要動畫"],onPageFinished: { (_ result:Any?) in
            print("這裡是在頁面開啟成功後回撥,這裡就會把我們上那邊urlParams裡面的識別符號傳過來")
        }) { (f: Bool) in
            print("頁面開啟")
        }
<!--這裡是我寫的值-->
FlutterBoostPlugin.open("first",urlParams:[kPageCallBackId:"HomePagecallbackId#1"],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"));
           }
複製程式碼

Dart裡面的程式碼(需要先在main裡面)我們在StatefulWidget下搞一個:

 void initState() {
    super.initState();
    FlutterBoost.singleton.registerPageBuilders(<String,PageBuilder>{
      'first': (String pageName,Map<String,dynamic> params,String _) =>
          FirstRouteWidget(),});
  }
複製程式碼

這樣就能開啟一個我們的flutter頁面了。 開啟時第一步,我們還要傳值過去原生傳值過去的程式碼

//        傳值給Flutter
  FlutterBoostPlugin.sharedInstance().sendEvent("data",arguments: ["name":"ryan","age":18])
複製程式碼

我們在dart裡面獲取值

//    監聽原生傳過來的值
  FlutterBoost.singleton.channel.addEventListener("data",(name,arguments) {
    print(arguments["age"]);
    return;
  });
複製程式碼

這樣就完成了第一步,感覺太多了寫的,Flutter返回原生傳值我寫在下一篇吧!

各位大佬:小弟正在Flutter學習中,如有什麼不妥的地方還望各位大佬斧正!!!