当前位置:   article > 正文

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

lanplay-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 … " 选项 ;

在这里插入图片描述

选择创建 " Empty Activity " ;

在这里插入图片描述

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

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 目录下 ;

在这里插入图片描述

Android 应用创建完成 :

在这里插入图片描述

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

在这里插入图片描述





二、关联 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')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2、配置 build.gradle


在 Android Module 下的 build.gradle 中 :

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

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

② 添加工程依赖 :

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

完整的配置文件如下 :

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')
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

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" />
  • 1
  • 2
  • 3
  • 4
  • 5

完整配置文件如下 :

<?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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26




三、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();
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

执行结果 :

请添加图片描述





四、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);
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

执行结果 : 点击 方式二 按钮 , 弹出 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);
            }
        });

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

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.
    );
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73




四、相关资源



参考资料 :


重要的专题 :


博客源码下载 :

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/810309
推荐阅读
相关标签
  

闽ICP备14008679号