现有Android项目中集成Flutter/Flutter混合开发实战(一)

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

内容简介:最近学了下Flutter,确实挺好的。单独的Flutter项目跑起来没有多大问题。目前也有一些混合开发的需求,所以找了一些文章来看,收获颇丰。

最近学了下Flutter,确实挺好的。

单独的Flutter项目跑起来没有多大问题。

目前也有一些混合开发的需求,所以找了一些文章来看,收获颇丰。

一.在现有项目上集成Flutter步骤详解

1.创建项目

这一步要注意,创建项目的目录, 不是,不是,不是 Android项目的根目录

现有Android项目中集成Flutter/Flutter混合开发实战(一)

↑不是它!

应该是下图的目录结构。flutter_hybrid目录即为我们要创建的flutter项目,FlutterrHybridDemo是我们现有的Android项目,叫什么都好。可以像我这样,建立一个空文件夹,把现有Android项目拖进去,这样方便查找和管理,不然flutter_hybrid会和FlutterHybridDemo平级,在一大堆项目中找这两个也怪麻烦的。

现有Android项目中集成Flutter/Flutter混合开发实战(一)

在这个目录下打开cmd,执行命令:

flutter create -t module xxxx(想要创建的flutter项目名)执行完复制代码

执行完后,一个和Android项目平级的flutter项目就已经创建好了。

2.添加flutter到当前Android项目

现有Android项目中集成Flutter/Flutter混合开发实战(一)

在Android项目根目录下的settings.gradle文件中,添加如下代码:

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        "flutter_hybrid/.android/include_flutter.groovy"
))
复制代码

现有Android项目中集成Flutter/Flutter混合开发实战(一)

然后,在项目的app目录下,build.gradle文件中,添加如下dependency:

implementation project(':flutter')复制代码

现有Android项目中集成Flutter/Flutter混合开发实战(一)

如上。添加完之后,准备工作就完成了。

二.集成Flutter

目前有两种方式可以添加

1.通过FlutterView方式添加到布局中

首先通过Flutter.createFlutterView方法来创建一个FlutterView类型的View。它有三个构造参数。

public static FlutterView createView(Activity activity, Lifecycle lifecycle, String initialRoute)复制代码

三个参数分别是:

1.Activity,即当前附着的Activity

2.LifeCycle,且是不能为空(NonNull)的,这也就要求我们必须用AppCompatActivity来承载FlutterView了,因为我试过了,如果我们的Activity继承自 android.app.Activity 是没有getLifeCycle()这个方法的。

public class FlutterViewActivity extends AppCompatActivity 复制代码

3.initialRoute

这是一个String类型的变量,可以理解为一个需要在Flutter中作为身份标记的变量,根据不同的标识返回不同的Flutter页面。

那么在Flutter文件中我们要这样写:

现有Android项目中集成Flutter/Flutter混合开发实战(一)

在 Flutter文件页面中的build方法中,我们可以拿到window对象,通过window.defaultRouteName(就是我们创建的时候传递的第三个参数)来区分返回不同界面

@override  Widget build(BuildContext context) {    switch(window.defaultRouteName){      case "flutter_view":        return _flutterHomeView(context);      default:        return Center(          child: Text('Unknown route: route', textDirection: TextDirection.ltr),        );
    }
}
Widget _flutterHomeView(context){    return Scaffold(      appBar: AppBar(title: Text('FlutterView的AppBar'),),      body: Center(        child: Text('现在是Flutter'),      ),    );  }
复制代码

在当前Activity的OnCreate方法中,执行

setContentView(R.layout.activity_flutter);
FlutterView flutterView = Flutter.createView(this, getLifecycle(), "flutter_view");
layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
addContentView(flutterView, layoutParams);
复制代码

由于addContentView这个方法必须要传递一个LayoutParams参数,我们就要用ViewGroup的LayoutParams。

这样执行的结果是:

现有Android项目中集成Flutter/Flutter混合开发实战(一)

可以看到Flutter页面已经作为一个View被添加到了Android原生界面中。这样我们就迈出了成功的第一步。

但是问题在于,我们看到FlutterView仍然不是全屏的,Android的ActionBar和Flutter的AppBar叠了两层额头,很不舒服。

这种情况,我们可以去掉两者任意一个。

比如在Android中,将当前Activity在AndroidManifest.xml文件中的theme属性改一下

<activity android:name=".FlutterViewActivity" android:theme="@style/AppTheme.NoActionBar"></activity>复制代码

那么Activity的ActionBar就去掉了

现有Android项目中集成Flutter/Flutter混合开发实战(一)

不过,现在状态栏不是沉浸式。关于这点,可以用Android代码在当前Activity中设置沉浸式状态栏,网上有很多成熟的解决方式,在此笔者就不提供了。

不过仅仅这样,我还是不满足的。因为我们的布局中还有一个TextView控件,这时候怎么没了...

<RelativeLayotu
    android:id="@+id/rl_container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/tv_native"
        android:textSize="50sp"
        android:text="原生文字控件"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>复制代码

所以我要的效果是这样的:

现有Android项目中集成Flutter/Flutter混合开发实战(一)

我们都知道,如果使用了RelativeLayout或者FrameLayout的话,View默认addView是可以重叠在一起的。所以我们的根布局如果是RelativeLayotu的话,要设置LayoutParams,添加Rule规定FlutterView要处于控件的下方。

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_flutter);
    rlContainer = findViewById(R.id.rl_container);
    rlContainer.addView(flutterView)
    RelativeLayout.LayoutParams rlLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    rlLayoutParams.addRule(BELOW,R.id.tv_native);
    llContainer.addView(flutterView,rlLayoutParams);
复制代码

不过我发现,addContentView()来添加的话, 即使是有LayoutParams也是会重叠在一起的。所以我的建议是,使用最外层容器(或者是你要添加进的那个容器).addView来添加。

当然,通过LinearLayout来作为容器,直接addView也是可以的。

通过尝试,发现只有addView的方式可以达到这样的效果。

现有Android项目中集成Flutter/Flutter混合开发实战(一)

不过这也足够我们开发中使用了。

未完待续...


以上所述就是小编给大家介绍的《现有Android项目中集成Flutter/Flutter混合开发实战(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Writing Windows VxDs and Device Drivers, Second Edition

Writing Windows VxDs and Device Drivers, Second Edition

Karen Hazzah / CMP / 1996-01-12 / USD 54.95

Software developer and author Karen Hazzah expands her original treatise on device drivers in the second edition of "Writing Windows VxDs and Device Drivers." The book and companion disk include the a......一起来看看 《Writing Windows VxDs and Device Drivers, Second Edition》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具