Flutter集成到现有项目功能依旧处于preview状态(2019.01.06)
操作环境:MAC/Linux
如果要集成到现有项目,需要切换Flutter SDK的channel到master,在终端执行:flutter channel master
创建Flutter项目模版,在终端执行:flutter create -t module flutter_module
,
创建完成后,终端执行:
$ cd flutter_module
$ pwd
/some/path/to/flutter_module
/some/path/to/flutter_module
路径就是Flutter项目的绝对路径。
此时项目主要目录应该如下:
+ flutter_dir
+ flutter_module #Flutter项目
+ .android/
+ .ios
+ lib
- main.dart #flutter项目入口代码
+ HostAndroidProject #待集成Flutter的Android项目
- settings.gradle
- build.gradle
+ app
+ HostIOSProject #待集成Flutter的iOS项目
+ HostIOSProject
+ HostIOSProjectTests
+ HostIOSProjectUITests
开始集成到项目。
Android项目SDK配置
27.1.1
, con.android.support:xxx:27.1.1+
打开Android工程,在settings.gradle
文件末尾追加:
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'
))
同步gradle sync
之后,宿主项项目在project
视图下变为:
+ Flutter
+ src
- build.gradle
+ HostAndroidProject
- settings.gradle
- build.gradle
+ app
- build.gradle
在HostAndroidProject/app/build.gradle
中添加项目依赖(也可以是需要接入Flutter项目的其他模块):
dependencies {
...
implementation project(':flutter')
...
}
开始编码,创建FlutterActivity
,在FlutterActivity
的onCreate
方法中修改代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_flutter)
// 创建FlutterView,router地址为Page,此处很重要
val content = Flutter.createView(this, lifecycle, "Page")
// 设置FlutterView宽高
val layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
// 添加FlutterView到Activity
addContentView(content, layoutParams)
}
Flutter集成到Android工作完成。
iOS项目集成Flutter基于CocoaPods, 在HostIOSProject
路径下创建podfile
文件,如果项目已经集成了pod可忽略创建podfile
文件。
poadfile文件中添加代码:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
target 'FlutteriOSIntergrationDemo' do
end
# 此处路径是flutter_module的绝对路径
flutter_application_path = '/some/path/to/flutter_module'
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
最后在终端执行pod install
使用xcode打开HostIOSProject.xcworkspace
,宿主项目的结构视图如下:
+ HostIOSProject
+ HostIOSProject
+ HostIOSProjectTests
+ HostIOSProjectUITests
+ Products
+ Pods
+ Frameworks
+ Pods
+ Podfile
+ Development Pods
+ Frameworks
+ Products
+ Targets Support Files
项目依赖添加完成,开始配置脚本:
选择 iOS应用的主 TARGET;
打开Build Phases Tab;
点击 + 按钮,并选择New Run Script;
展开Run Script,在Shell区域添加如下脚本代码:
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
然后拖拽新建的Run Script到Target Dependencies之后。
打开Build SettingsTab ,找到Enable BitCode选项,改为NO,如果已经设置过,可忽略此步骤。
项目配置完成,开始编码:
AppDelegate.h
#import
// 添加flutter头文件
#import
// 修改app代理的父类为FlutterAppDelegate
@interface AppDelegate : FlutterAppDelegate
@end
AppDelegate.m
#import "AppDelegate.h"
// 添加头文件
#import
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// 重写application:didFinishLaunchingWithOptions:方法
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
ViewController.m
#import "ViewController.h"
#import
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 198, 45);
btn.layer.borderWidth = 1.0f;
btn.layer.borderColor = UIColor.grayColor.CGColor;
btn.layer.cornerRadius = 10;
[btn setTitle:@"Jump" forState:UIControlStateNormal];
[btn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
// 设置按钮点击事件为jump
[btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)jump {
NSLog(@"Just jump to flutter");
// 创建FlutterViewController,并跳转到Flutter页面
FlutterViewController *ctrl = [[FlutterViewController alloc] init];
// 设置Flutter页面的router为Page
[ctrl setInitialRoute:@"Page"];
[self presentViewController:ctrl animated:YES completion:nil];
}
@end
致此,iOS项目集成Flutter完成。
设置flutter代码入口。
修改flutter_module/lib/main.dart
代码。
import 'package:flutter/material.dart';
import 'dart:ui'; // window
void main() => runApp(_widgetForRoute(window.defaultRouteName));
// 路由方法
Widget _widgetForRoute(String route) {
switch(route) {
// 此处很重要,iOS/Android项目中均设置了路由到flutter页面的路由参数
case 'Page':
return MyApp();
default:
return Center(
child: Text(
"Unknown route: $route",
textDirection: TextDirection.ltr,
),
);
}
}
集成工作全部完成。