简介

Flutter混合栈开发插件,解决引擎复用,双端路由统一等混合栈开发遇到的问题。

推荐使用脚手架工具进行集成flutter-integration-tool

Getting Started

添加pubspec引用

dependencies:
  flutter_integration: ^0.0.*
  
dev_dependencies:
  flutter_integration: ^0.0.*

android示例

完整示例见 flutter-integration-demo-android

  1. 调用初始化
public class ExampleApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        FlutterIntegrationManager.sharedInstance().initEngine(this);
    }
}
  1. Flutter代码接入FlutterIntegration.builder,设置IntegrationRouter
import 'package:flutter/material.dart';
import 'package:flutter_integration/flutter_integration.dart';
import 'package:flutter_integration/Router/integration_router.dart';

void main() => runApp(MyHomePage());

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final TransitionBuilder _builder = FlutterIntegration.builder();

  @override
  void initState() {
    super.initState();
    print('initState');

    FlutterIntegration.router = DefaultRouter();
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    return MaterialApp(
      builder: _builder,
      home: Container(),
    );
  }
}

class DefaultRouter extends IntegrationRouter {
  @override
  Widget getWidgetByRouteName(String routeName, params) {
    switch (routeName) {
      case 'test':
        return Container(
          height: 200,
          width: 200,
          child: Image.network(
              'https://www.baidu.com/img/bd_logo1.png'),
        );
        break;
      default:
        break;
    }
    return null;
  }
}

  1. Android中得到TestActivity中,使用FlutterIntegrationFragment.newInstance("test")即可,test为页面路由
package com.example.flutter_integration_demo_android;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.tencent.flutter_integration.FlutterIntegrationFragment;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

public class TestActivity extends FragmentActivity {
    // Define a tag String to represent the FlutterFragment within this
    // Activity's FragmentManager. This value can be whatever you'd like.
    private static final String TAG_FLUTTER_FRAGMENT = "flutter_fragment";

    FlutterIntegrationFragment flutterFragment = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Inflate a layout that has a container for your FlutterFragment. For
        // this example, assume that a FrameLayout exists with an ID of
        // R.id.fragment_container.
        setContentView(R.layout.test_activity_layout);

        findViewById(R.id.open).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(TestActivity.this, TestActivity.class);
                startActivity(intent);
            }
        });
        // Get a reference to the Activity's FragmentManager to add a new
        // FlutterFragment, or find an existing one.
        FragmentManager fragmentManager = getSupportFragmentManager();

        // Attempt to find an existing FlutterFragment, in case this is not the
        // first time that onCreate() was run.
        flutterFragment = (FlutterIntegrationFragment) fragmentManager.findFragmentByTag(TAG_FLUTTER_FRAGMENT);

        // Create and attach a FlutterFragment if one does not exist.
        if (flutterFragment == null) {
            flutterFragment = FlutterIntegrationFragment.newInstance("test");
            fragmentManager
                    .beginTransaction()
                    .add(R.id.fragment_container,
                            flutterFragment,
                            TAG_FLUTTER_FRAGMENT)
                    .commit();
        }
    }

    @Override
    public void onPostResume() {
        super.onPostResume();
        flutterFragment.onPostResume();
    }

    @Override
    protected void onNewIntent(@NonNull Intent intent) {
        super.onNewIntent(intent);
        flutterFragment.onNewIntent(intent);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        flutterFragment.onBackPressed();
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode,
            @NonNull String[] permissions,
            @NonNull int[] grantResults
    ) {
        super.onRequestPermissionsResult(
                requestCode,
                permissions,
                grantResults
        );
        flutterFragment.onRequestPermissionsResult(
                requestCode,
                permissions,
                grantResults
        );
    }

    @Override
    public void onUserLeaveHint() {
        super.onUserLeaveHint();
        flutterFragment.onUserLeaveHint();
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        flutterFragment.onTrimMemory(level);
    }

}

ios示例

完整示例见 flutter-integration-demo

  1. 调用初始化[[FlutterIntegrationManager sharedInstance] initEngine]

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [[FlutterIntegrationManager sharedInstance] initEngine];
    ...
}
  1. Flutter代码接入FlutterIntegration.builder,设置IntegrationRouter
import 'package:flutter/material.dart';
import 'package:flutter_integration/flutter_integration.dart';
import 'package:flutter_integration/Router/integration_router.dart';

void main() => runApp(MyHomePage());

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final TransitionBuilder _builder = FlutterIntegration.builder();

  @override
  void initState() {
    super.initState();
    print('initState');

    FlutterIntegration.router = DefaultRouter();
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    return MaterialApp(
      builder: _builder,
      home: Container(),
    );
  }
}

class DefaultRouter extends IntegrationRouter {
  @override
  Widget getWidgetByRouteName(String routeName, params) {
    switch (routeName) {
      case 'test':
        return Container(
          height: 200,
          width: 200,
          child: Image.network(
              'https://www.baidu.com/img/bd_logo1.png'),
        );
        break;
      default:
        break;
    }
    return null;
  }
}

  1. iOS层调用[[FlutterIntegrationHostViewController alloc] initWithRouteName:@"test" params:nil]启动Flutter页面即可,test为路由
#import "AppDelegate.h"

#import <flutter_integration/FlutterIntegrationManager.h>
#import <flutter_integration/FlutterIntegrationHostViewController.h>

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [[FlutterIntegrationManager sharedInstance] initEngine];
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = UIColor.whiteColor;
    [self.window makeKeyAndVisible];

    UITabBarController *tabVC = [[UITabBarController alloc] init];
    UINavigationController *rvc = [[UINavigationController alloc] initWithRootViewController:tabVC];

    UIViewController *vc1 = [[UIViewController alloc] init];
    vc1.view.backgroundColor = UIColor.whiteColor;
    vc1.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"tab1" image:nil tag:0];
    vc1.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -16);
    
    FlutterIntegrationHostViewController *vc2 = [[FlutterIntegrationHostViewController alloc] initWithRouteName:@"test" params:nil];
    
    vc2.view.backgroundColor = UIColor.grayColor;
    vc2.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"tab2" image:nil tag:0];
    vc2.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -16);
    tabVC.viewControllers = @[vc1, vc2];

    self.window.rootViewController = rvc;
    return YES;
}

@end

Libraries

IntegrationLogger
flutter_integration
integration_native_channel
integration_page_container
integration_router