0
点赞
收藏
分享

微信扫一扫

【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )



文章目录


  • ​​前言​​
  • ​​一、创建 Android 项目​​
  • ​​二、关联 Android 工程与 Flutter Module 工程​​

  • ​​1、配置 Flutter Module工程​​
  • ​​2、配置 build.gradle​​
  • ​​3、配置 AndroidManifest.xml​​

  • ​​三、Activity 中嵌入 FlutterFragment 页面​​
  • ​​四、Activity 中启动 FlutterActivity 页面​​
  • ​​五、完整代码示例​​

  • ​​1、Android 主界面代码示例​​
  • ​​2、Flutter 完整代码示例​​

  • ​​四、相关资源​​


前言

在上一篇博客 ​​【Flutter】Flutter 混合开发 ( 简介 | Flutter 混合开发集成步骤 | 创建 Flutter Module )​​ 中 , 创建了 Flutter Module 工程 ;

本篇博客开始创建 Android 工程 , 并将两个工程进行关联 ;



Flutter 混合开发集成步骤 :


  • ① 在 Android Studio 中创建 Flutter Module ;
  • ② 为 Native 应用添加 Flutter Module 依赖 ;
  • ③ 在 Native 应用 ( Android / iOS 应用 ) 中 , 调用 Flutter Module 模块 ;
  • ④ 编写 Flutter Module 中的 Dart 代码 ;
  • ⑤ 运行 Flutter 混合应用 ;
  • ⑥ 项目的 热重启 / 重新加载 ;
  • ⑦ 调试 Dart 代码 ;
  • ⑧ 应用发布 ;





一、创建 Android 项目


在 Android Studio 中 , 在菜单栏中 , 选择 " File -> New -> New Project … " 选项 ;

【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )_Flutter混合开发

选择创建 " Empty Activity " ;

【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )_Flutter混合开发_02

这里要特别注意路径的设置 ,

Flutter Module 工程的路径是 :​ D:\002_Project\002_Android_Learn\flutter_hybrid\flutter_module

Android 工程的路径是 :​ D:\002_Project\002_Android_Learn\flutter_hybrid\flutter_native

上面两个工程的路径都在 D:\002_Project\002_Android_Learn\flutter_hybrid 目录下 ;

【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )_flutter_03

Android 应用创建完成 :

【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )_android_04

Android 工程 与 Flutter Module 工程 , 都在同一个目录中 ;

【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )_原力计划_05






二、关联 Android 工程与 Flutter Module 工程


Android 工程的路径 与 Flutter Module 工程路径 , 否符合如下要求 :


  • Flutter Module 工程的路径是 :​ D:\002_Project\002_Android_Learn\flutter_hybrid\flutter_module
  • Android 工程的路径是 :​ D:\002_Project\002_Android_Learn\flutter_hybrid\flutter_native
  • 上面两个工程的路径都在 D:\002_Project\002_Android_Learn\flutter_hybrid 目录下 ;


1、配置 Flutter Module工程



在 Android 工程的 settings.gradle 进行如下配置 :​ 这样配置后 , Flutter 工程就会被编译成一个 Android Library Module , 名称是 flutter ;

rootProject.name = "flutter_native"
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'
))
include ':flutter_module'
project(':flutter_module').projectDir = new File('../flutter_module')



2、配置 build.gradle



在 Android Module 下的 build.gradle 中 :

① 配置最低支持版本 minSdkVersion 16+ , 因为 Flutter 最低支持版本是 16 ;

// Flutter 最低支持版本是 16
minSdkVersion 18

② 添加工程依赖 :

// 在 settings.gradle 中配置的脚本 , 会自动关联到 Flutter 模块
implementation project(':flutter')

完整的配置文件如下 :

plugins {
id 'com.android.application'
}

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"

defaultConfig {
applicationId "com.example.flutter_native"
// Flutter 最低支持版本是 16
minSdkVersion 18
targetSdkVersion 30
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {

implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

// 在 settings.gradle 中配置的脚本 , 会自动关联到 Flutter 模块
implementation project(':flutter')
}



3、配置 AndroidManifest.xml



将 io.flutter.embedding.android.FlutterActivity 配置到 AndroidManifest.xml 清单文件中 ;

<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />

完整配置文件如下 :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flutter_native">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Flutter_native">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />
</application>

</manifest>






三、Activity 中嵌入 FlutterFragment 页面


在 Activity 中 , 将 Flutter 页面作为 Fragment , 嵌入到 Activity 中 ;

findViewById(R.id.flutter1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
// 创建 FlutterFragment
fragmentTransaction.replace(R.id.frame, FlutterFragment.createDefault());
fragmentTransaction.commit();
}
});



执行结果 :






四、Activity 中启动 FlutterActivity 页面


将 Flutter 页面当做一个新的 Activity 启动 ;

findViewById(R.id.flutter2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = FlutterActivity
.withNewEngine()
.initialRoute("Android 启动 FlutterActivity")
.build(MainActivity.this);
//intent.putExtra("initParams", "Android 中 Activity 启动 Flutter");
startActivity(intent);
}
});

执行结果 :​ 点击 方式二 按钮 , 弹出 FlutterActivity ;






五、完整代码示例


这里只贴出主界面完整代码 , 具体的配置参数 , 查看 GitHub 或者 CSDN 源码快照 ;



1、Android 主界面代码示例



package com.example.flutter_native;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;

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

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.android.FlutterFragment;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

findViewById(R.id.flutter1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
// 创建 FlutterFragment
fragmentTransaction.replace(R.id.frame, FlutterFragment.createDefault());
fragmentTransaction.commit();
}
});

findViewById(R.id.flutter2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = FlutterActivity
.withNewEngine()
.initialRoute("Android 启动 FlutterActivity")
.build(MainActivity.this);
//intent.putExtra("initParams", "Android 中 Activity 启动 Flutter");
startActivity(intent);
}
});

}
}



2、Flutter 完整代码示例



import 'package:flutter/material.dart';
import 'dart:ui';

void main() => runApp(
/// 该构造方法中传入从 Android 中传递来的参数
MyApp(initParams: window.defaultRouteName,)
);

class MyApp extends StatelessWidget {
/// 这是从 Android 中传递来的参数
final String initParams;
/// 构造方法 , 获取从 Android 中传递来的参数
const MyApp({Key? key, required this.initParams}):super(key: key);

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: initParams),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;

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

class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}






四、相关资源


参考资料 :


  • Flutter 官网 :​ ​​https://flutter.dev/​​
  • Flutter 插件下载地址 :​ ​​https://pub.dev/packages​​
  • Flutter 开发文档 :​ ​​https://flutter.cn/docs​​ ​( 强烈推荐 )
  • 官方 GitHub 地址​ : ​​https://github.com/flutter​​
  • Flutter 中文社区 :​ ​​https://flutter.cn/​​
  • Flutter 实用教程 :​ ​​https://flutter.cn/docs/cookbook​​
  • Flutter CodeLab :​ ​​https://codelabs.flutter-io.cn/​​
  • Dart 中文文档 :​ ​​https://dart.cn/​​
  • Dart 开发者官网 :​ ​​https://api.dart.dev/​​
  • Flutter 中文网 :​ ​​https://flutterchina.club/​​​ , ​​http://flutter.axuer.com/docs/​​
  • Flutter 相关问题 :​ ​​https://flutterchina.club/faq/​​ ( 入门阶段推荐看一遍 )
  • Flutter 实战电子书 :​​ ​​https://book.flutterchina.club/chapter1/​​
  • Dart 语言练习网站 :​ ​​https://dartpad.dartlang.org/​​


重要的专题 :

  • Flutter 动画参考文档 :​ ​​https://flutterchina.club/animations/​​


博客源码下载 :


  • GitHub 地址 :​ ( 随博客进度一直更新 , 有可能没有本博客的源码 )

  • Flutter Module 工程 :​ ​​https://github.com/han1202012/flutter_module​​
  • Android 应用 :​ ​​https://github.com/han1202012/flutter_native​​
  • 注意 : 上面两个工程要放在同一个目录中 , 否则编译不通过 ;



举报

相关推荐

0 条评论