android/ ios,在Android和iOS中集成flutter

flutter可能是未来跨平台开发的又一技术框架,那么对于一个app,我们不可能完全用flutter来开发,那么就意味着我们需要在已有的Android和iOS代码中去集成flutter。目前这一技术还处于预览状态,并且还要切换flutter的channel为mater分支。如下,官方原话:

3f93db32c2afe50a98c4c6aa317210d3.png

那么我们在集成之前需要查看现在flutter处于什么渠道:

652657d3df0f0dfc46ab8950f1fd9ba6.png

我的是处于master分支,如果你以前没改过的话,应该是beta分支,那么可以执行:

flutter channel master

进行切换。

下面正式开始集成Android和iOS。

Android

首先用Android studio创建一个Android工程,步骤不做介绍了。然后在Android工程的根目录执行一下命令:

flutter create -t module my_flutter

来创建一个flutter的module,成功之后,目录结构如下:

213ea412e6c53f193d059542705bc6e7.png

接着我们来修改一下Android功能里的gradle文件:

首先是app的setting.gradle文件,添加如下:

include ':app'

setBinding(new Binding([gradle: this]))

evaluate(new File(

settingsDir.parentFile,

'my_flutter/.android/include_flutter.groovy'

))

目的就是去加载指定目录的include_flutter.groovy文件,那么我们查看一下这个文件:

// Generated file. Do not edit.

def scriptFile = getClass().protectionDomain.codeSource.location.path

def flutterProjectRoot = new File(scriptFile).parentFile.parentFile

gradle.include ':flutter'

gradle.project(':flutter').projectDir = new File(flutterProjectRoot, '.android/Flutter')

def plugins = new Properties()

def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')

if (pluginsFile.exists()) {

pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }

}

plugins.each { name, path ->

def pluginDirectory = flutterProjectRoot.toPath().resolve(path).resolve('android').toFile()

gradle.include ":$name"

gradle.project(":$name").projectDir = pluginDirectory

}

gradle.getGradle().projectsLoaded { g ->

g.rootProject.afterEvaluate { p ->

p.subprojects { sp ->

if (sp.name != 'flutter') {

sp.evaluationDependsOn(':flutter')

}

}

}

}

其中最重要的一段代码,就是include ':flutter',意思就是flutter这个module要参与编译。

接着在app层级(不是project层)的build.gradle文件中添加依赖:

dependencies {

implementation project(':flutter')

:

}

OK配置阶段结束,我们开始先写Android代码,在activity中添加一个button,当我们点击它时,将加载flutter布局,代码如下:

public class MainActivity extends AppCompatActivity {

private TextView button;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

button = findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

FragmentTransaction tx = getSupportFragmentManager().beginTransaction();

tx.replace(R.id.container, Flutter.createFragment("route1"));

tx.commit();

// View flutterView = Flutter.createView(MainActivity.this,getLifecycle(),"route1");

// FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(100,100);

// params.leftMargin = 100;

// params.topMargin = 200;

// addContentView(flutterView,params);

}

});

}

}

这里有两种实现方式,一种是使用fragment,一种是使用FlutterView。代码中的route1字符串则是flutter代码中定义的,接下来就开始写flutter代码:

import 'dart:ui';

import 'package:flutter/material.dart';

void main() => runApp(_widgetForRoute(window.defaultRouteName));

Widget _widgetForRoute(String route) {

switch (route) {

case 'route1':

return SomeWidget();

case 'route2':

return SomeWidget();

default:

return Center(

child: Text('Unknown route: $route', textDirection: TextDirection.ltr),

);

}

}

class SomeWidget extends StatelessWidget{

@override

Widget build(BuildContext context) {

// TODO: implement build

return Container(

width: 100,

height: 100,

color: Color(0xFF00FF00),

child: Center(

child: Text("hello",textDirection: TextDirection.ltr,),

),

);

}

}

这里可以看到对rout1的定义。

写到这里代码部分就完成了,然后运行android项目,就可以看到效果了。

ios

首先也是执行:

flutter create -t module my_flutter

生成一个flutter工程,由于在Android集成中已经做了这一步,故跳过。然后用Xcode创建一个iOS工程,创建完成之后,目录如下:

61369bd213ee486cd9d8249cc61e021e.png

下面为工程添加flutter的依赖,这里要使用cocoapods,若以前没有安装过,则执行命令:

sudo gem install cocoapods

然后在iOS工程的根目录创建Podfile文件,命令为:

touch Podfile

然后修改podfile文件,如下:

target 'ios4Flutter' do

platform:ios,'8.0'

flutter_application_path = '../my_flutter/'

eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)

end

其中ios4Flutter为我的iOS工程名,flutter_application_path为flutter工程的根目录。

最后执行:

pod install

完成项目的依赖,效果如下:

d604023730cf8d300657691551afff24.png

之后点击.xcworkSpace文件打开iOS工程,找到Build Phases目录,新建一个Script Phase,粘贴下面的命令:

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

到text area,如下图:

2c0495499e4907b5deeeebd73629525e.png

配置完成之后,⌘B来build工程。如果没有报错,那么部署成功。下面开始写代码:

在AppDelegate.h中:

#import

#import

@interface AppDelegate : FlutterAppDelegate

@end

AppDelegate.m:

#import // Only if you have Flutter Plugins

#include "AppDelegate.h"

@implementation AppDelegate

// This override can be omitted if you do not have any Flutter Plugins.

- (BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

[GeneratedPluginRegistrant registerWithRegistry:self];

return [super application:application didFinishLaunchingWithOptions:launchOptions];

}

@end

ViewController.m:

#import

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

[button addTarget:self

action:@selector(handleButtonAction)

forControlEvents:UIControlEventTouchUpInside];

[button setTitle:@"Press me" forState:UIControlStateNormal];

[button setBackgroundColor:[UIColor blueColor]];

button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);

[self.view addSubview:button];

}

- (void)handleButtonAction {

FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];

[flutterViewController setInitialRoute:@"route1"];

[self presentViewController:flutterViewController animated:false completion:nil];

}

@end

OK,oc代码编写完成,运行app,呈现效果。

Hot restart/reload and debugging Dart code

我们可以运用dart语言的特性实现 hot reload,首先在flutter的根目录执行:

flutter attach

如下:

805bf074e9b1ebe384e9453633ae1e06.png

当运行完app,点击按钮进入flutter的view时,终端状态如下:

53d3245f22cdc8d8c29ef6359105e696.png

当我们再次修改dart代码,保存之后,在命令中输入r即可hot reload。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值