在Android和iOS中集成flutter 原 荐

栏目: IOS · Android · 发布时间: 5年前

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

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

在Android和iOS中集成flutter 原 荐

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

在Android和iOS中集成flutter 原 荐

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

flutter channel master

进行切换。

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

Android

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

flutter create -t module my_flutter

来创建一个flutter的module,成功之后,目录结构如下: 在Android和iOS中集成flutter 原 荐

接着我们来修改一下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工程,创建完成之后,目录如下:

在Android和iOS中集成flutter 原 荐

下面为工程添加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

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

在Android和iOS中集成flutter 原 荐

之后点击.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,如下图:

在Android和iOS中集成flutter 原 荐

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

在AppDelegate.h中:

#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>

@interface AppDelegate : FlutterAppDelegate
@end

AppDelegate.m:

#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h> // 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 <Flutter/Flutter.h>
#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

如下:

在Android和iOS中集成flutter 原 荐

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

在Android和iOS中集成flutter 原 荐

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


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript

JavaScript

Douglas Crockford / Yahoo Press / 2008-5 / GBP 23.99

Most programming languages contain good and bad parts, but JavaScript has more than its share of the bad, having been developed and released in a hurry before it could be refined. This authoritative b......一起来看看 《JavaScript》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具