在Android中集成Flutter的學習筆記

Flutter可能是未來跨平臺開發的又一技術框架,那麼對於一個app,我們不可能完全用flutter來開發,那麼就意味着我們需要在已有的Android和iOS代碼中去集成flutter。目前這一技術還處於預覽狀態,並且還要切換flutter的channel爲mater分支。如下,官方原話:

那麼我們在集成之前需要查看現在flutter處於什麼渠道:

我的是處於master分支,如果你以前沒改過的話,應該是beta分支,那麼可以執行:

flutter channel master

進行切換。

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

Android

首先用Android studio創建一個Android工程,步驟不做介紹了。然後在Android工程的根目錄執行一下命令:

flutter create -t module my_flutter

來創建一個flutter的module,成功之後,目錄結構如下:

接着我們來修改一下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項目,就可以看到效果了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章