zoukankan      html  css  js  c++  java
  • flutter和iOS混编,并且在iOS中控制跳转不同的flutter页面

    //main
    
    import 'package:flutter/material.dart';
    import 'package:use_with_native/native_system_call.dart';
    import 'test_page_blue.dart';
    import 'test_page_red.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: '原生和Flutter相互跳转',
          theme: ThemeData(
            primarySwatch: Colors.green,
          ),
          home: MyHomePage(
            title: '',
            pageType: '',
          ),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title, this.pageType}) : super(key: key);
    
      final String title;
      final String pageType;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      String pageType = '';
      String identity = '';
      Map param = Map();
      @override
      void initState() {
        super.initState();
        getCurrentPageType();
      }
    
      @override
      Widget build(BuildContext context) {
        return createCurrentPage();
      }
    
      @override
      void dispose() {
        super.dispose();
        NativeSystemCall.removeStateWithIdentity(this.identity);
      }
    
      getCurrentPageType() async {
        try {
          Map result = await NativeSystemCall.systemCall
              .invokeMapMethod('ui', {'event': 'getNewPageInfo'});
          String type = result['type'];
          String identity = result['identity'];
          Map param = result['param'];
          setState(() {
            this.pageType = type;
            this.identity = identity;
            this.param = param == null ? Map() : param;
            NativeSystemCall.addStateWithIdentity(this, identity);
          });
        } catch (e) {}
      }
    
      closeThisPage() {
        try {
          NativeSystemCall.systemCall
              .invokeMethod('ui', {'event': 'dismissTopPage'});
        } catch (e) {}
      }
    
      Widget createCurrentPage() {
        Widget pageContent = Center();
        switch (pageType) {
          case 'red':
            pageContent = TestPageRed(
              param: this.param,
              backEvent: closeThisPage,
            );
            break;
          case 'blue':
            pageContent = TestPageBlue(
              param: this.param,
              backEvent: closeThisPage,
            );
            break;
          default:
        }
        return pageContent;
      }
    }
    //native_system_call.dart
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class NativeSystemCall {
      static Map stateCollection = Map();
      static MethodChannel systemCall =
          MethodChannel('common.flutter.caller/message');
    
      static findState(String identity) {
        State result = stateCollection[identity];
        return result;
      }
    
      static addStateWithIdentity(State state, String identity) {
        stateCollection[identity] = state;
      }
    
      static removeStateWithIdentity(String identity) {
        stateCollection.remove(identity);
      }
    }
    import 'package:flutter/material.dart';
    
    class TestPageRed extends StatelessWidget {
      TestPageRed({Key key, this.param, this.backEvent}) : super(key: key);
      final Map param;
      final Function backEvent;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.red,
            leading: BackButton(
              onPressed: backEvent,
            ),
            title: Text('测试页面A'),
          ),
          body: Container(
            child: Image(
              image: NetworkImage(
                  'https://avatars2.githubusercontent.com/u/41252899?s=460&v=4'),
            ),
          ),
        );
      }
    }
    //
    //  FlutterHelper.m
    //  Runner
    //
    //  Created by wangjiayuan on 2021/4/29.
    //
    
    #import "FlutterHelper.h"
    #import <objc/runtime.h>
    
    @interface FlutterViewController (FlutterHelper)
    
    @property (nonatomic, copy, readwrite) NSString *pageIdentify;
    
    @end
    
    @implementation FlutterViewController (FlutterHelper)
    
    - (NSString *)pageIdentify {
        return objc_getAssociatedObject(self, "pageIdentify");
    }
    
    - (void)setPageIdentify:(NSString *)pageIdentify {
        objc_setAssociatedObject(self, "pageIdentify", pageIdentify, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    @end
    
    @interface FlutterNewPageInfo : NSObject
    
    @property (nonatomic, copy) NSString *pageType;
    @property (nonatomic, copy) NSString *pageIdentify;
    @property (nonatomic, strong) NSDictionary *pageParam;
    
    @end
    
    @implementation FlutterNewPageInfo
    
    
    @end
    
    @interface FlutterHelper()
    
    @property (nonatomic, strong) FlutterNewPageInfo *pageInfo;
    @property (nonatomic, strong) NSMutableArray <FlutterViewController*> *presentFlutterControllers;
    
    @end
    
    @implementation FlutterHelper
    
    + (instancetype)helper {
        static FlutterHelper *helper = nil;
        if (!helper) {
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                helper = [[self alloc] init];
            });
        }
        return helper;
    }
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            self.presentFlutterControllers = [NSMutableArray array];
        }
        return self;
    }
    
    - (void)openNewFlutterPage:(NSString *)pageType {
        self.pageInfo = [FlutterNewPageInfo new];
        self.pageInfo.pageIdentify = [NSString stringWithFormat:@"%.0f%04d", [NSDate date].timeIntervalSince1970, arc4random()%10000];
        self.pageInfo.pageParam = @{};
        self.pageInfo.pageType = pageType;
        FlutterEngine *engine = [[FlutterEngine alloc] initWithName:[NSString stringWithFormat:@"app.flutter.engine:%@", self.pageInfo.pageIdentify]];
        [engine run];
        FlutterViewController *controller = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
        controller.pageIdentify = self.pageInfo.pageIdentify;

       [GeneratedPluginRegistrant registerWithRegistry:controller.pluginRegistry];

        FlutterMethodChannel *caller = [FlutterMethodChannel methodChannelWithName:@"common.flutter.caller/message" binaryMessenger:controller.binaryMessenger];
        __weak typeof(self) weakSelf = self;
        [caller setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf execFlutterCall:call callback:result];
        }];
        controller.modalPresentationStyle = UIModalPresentationFullScreen;
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:controller animated:YES completion:nil];
            [self.presentFlutterControllers addObject:controller];
        });
    }
    
    - (void)execFlutterCall:(FlutterMethodCall*)call callback:(FlutterResult)callback {
        NSString *method = call.method;
        if ([method isEqualToString:@"ui"]) {
            if ([call.arguments isKindOfClass:[NSDictionary class]]) {
                NSDictionary *info = call.arguments;
                NSString *event = info[@"event"];
                if ([event isEqualToString:@"getNewPageInfo"]) {
                    !callback?:callback(@{
                        @"type": self.pageInfo.pageType ? : @"",
                        @"identity": self.pageInfo.pageIdentify ? : @"",
                        @"param": self.pageInfo.pageParam ? : @{},
                                        });
                    self.pageInfo = nil;
                }
                if ([event isEqualToString:@"dismissTopPage"]) {
                    if (self.presentFlutterControllers.count != 0) {
                        FlutterViewController *controller = self.presentFlutterControllers[self.presentFlutterControllers.count - 1];
                        [self.presentFlutterControllers removeObject:controller];
                        [controller dismissViewControllerAnimated:YES completion:^{
                            !callback ? : callback(@(YES));
                        }];
                    } else {
                        !callback ? : callback(@(NO));
                    }
                }
            }
        }
    }
    
    @end

    AppDelegate可以和正常的写法一致,每新建一个FlutterEngine就是相当于从新创建一个Flutter运行环境,如果公用一个的话,会出现 State 的 initState 只执行一次,可以理解成,多个 FlutterViewController 负责渲染出来的是同一份 Flutter页面

  • 相关阅读:
    git 配置免密上传,配置ssh key
    spring @value 为什么没有获取到值
    idea 下maven 导入本地jar,以及导入之后 java不能引用问题
    在git远程仓创建项目之后,提交本地项目的使用方法
    mysql 查询数据库参数命令
    spring Existing transaction found for transaction marked with propagation 'never' 解决
    nginx for ubuntu
    spring中for循环中事务
    面向接口编程详解(一)——思想基础
    实战MEF(5):导出元数据
  • 原文地址:https://www.cnblogs.com/yuxiaoyiyou/p/14718547.html
Copyright © 2011-2022 走看看