原生Android项目添加Flutter Module

公司原先iOS和Android都用原生开发,效率低成本高。 于是和team中的App开发小伙伴讨论了一下,决定用Flutter改进。 又不能一下子把整个原生App废弃,于是决定把一个相对独立的模块用Flutter实现后,导入到原生项目中。

这里记录下用Flutter实现一个module并导入Android原生项目的过程。
1: 安装Android Studio,新建一个Android原生项目

2:下载Flutter SDK,添加环境变量,参考:https://flutter.cn/docs/get-started/install
运行Flutter doctor,查看安装情况。 如遇以下异常

可通过Android Studio安装以下组件解决

为Android Studio安装Flutter插件

3:通过Android Studio新建Flutter Module, new flutter project ->

选择Flutter SDK地址

注意Project Type选择Module

4:配置原生Android项目
根目录下的settings.gradle 文件尾部加入以下配置。 其中的FlutterModule为路径,假设Flutter Module和Native Android项目在同一级目录

setBinding(new Binding([gradle: this]))                                
evaluate(new File(                                                    
        settingsDir.parentFile,                                             
        'FlutterModule/.android/include_flutter.groovy'                       
)) 

以下配置为了解决Error:repository 'maven' was added by plugin class 'FlutterPlugin', 参考:https://github.com/flutter/flutter/issues/85014
根目录下的build.gradle增加

allprojects {
    repositories {
        google()
        jcenter()
    }
}

根目录下的settings.gradle,dependencyResolutionManagement -> repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
替换为repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)

在使用flutter module的Android module下的build.gradle中dependencies添加
implementation project(path: ':flutter')

5:build项目

6:
AndroidManifest.xml中增加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:theme="@style/Theme.NativeApp.NoActionBar"
           android:windowSoftInputMode="adjustResize" >
       </activity>

参考:https://docs.flutter.dev/development/add-to-app/android/project-setup

但是
实测下来,自己写配置导入的方式不work,运行项目的时候会报错。 所以尝试用Android Studio自带的导入

导入后可在导航栏中见到

并且可以运行

!注意,必须全程在VPN环境下安装,否则会出现某些依赖,如io.flutter.embedding.android.FlutterActivity
添加FlutterActivity
参考:https://blog.csdn.net/mengks1987/article/details/109321951

修改MainActivity.kt, 代码如下

package com.example.myapplication

import android.content.Intent
import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import android.view.Menu
import android.view.MenuItem
import com.example.myapplication.databinding.ActivityMainBinding
import io.flutter.embedding.android.FlutterActivity

class MainActivity : FlutterActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.btnNext.setOnClickListener {
            startActivity(Intent(this,SecondFlutterActivity::class.java))
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        return when (item.itemId) {
            R.id.action_settings -> true
            else -> super.onOptionsItemSelected(item)
        }
    }

}

修改res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.MyApplication.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="226dp"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/Theme.MyApplication.PopupOverlay" />

        <Button
            android:id="@+id/btnNext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Go to page 2" />
    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

添加SecondFlutterActivity.kt

package com.example.myapplication
import io.flutter.embedding.android.FlutterActivity

class SecondFlutterActivity:FlutterActivity()  {
}

res/layout/下添加second_flutter_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondFlutterActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.MyApplication.AppBarOverlay">
    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

运行后效果如下

单击"go to page 2"

源码地址链接

posted @ 2022-08-10 08:20  老胡Andy  阅读(1604)  评论(0编辑  收藏  举报