前言
Flutter 支持作為 android Moudle 出現(xiàn)在項(xiàng)目中.這樣就可以在 已有的項(xiàng)目中 使用.
雖然現(xiàn)在Flutter 比較受關(guān)注,但是和weex 一樣 ,大部分都只是在觀望 不是真正的進(jìn)行使用.所以 如果用還是混合開發(fā) 原生+Flutter 方式比較合適(自我感覺(jué)).
寫一個(gè)demo 進(jìn)行Android及Flutter 交互.(IOS 方法基本一致).
Flutter 調(diào)用 android 硬件的插件還比較匱乏 比如 各種傳感器, 自定義相機(jī) 所以就會(huì)用到 Flutter 調(diào)用android 及android 原生調(diào)用 Flutter的方法.
本例子中會(huì)實(shí)現(xiàn).
(1) 原有的android 應(yīng)用程序嵌入 FlutterView
(2) Flutter 代碼調(diào)用Android 原生方法進(jìn)行頁(yè)面跳轉(zhuǎn)及傳值
(3) Android原生 調(diào)用 Flutter 方法 進(jìn)行傳值
步驟
新建一個(gè) android 項(xiàng)目
然后在 同級(jí)目錄創(chuàng)建一個(gè)Flutter Moudle
然后 導(dǎo)入 Flutter Moudle
Moudle 導(dǎo)入成功后 項(xiàng)目結(jié)構(gòu)
app 目錄下的
build.gradle 中 新增了
implementation project(':flutter')
項(xiàng)目目錄下的
settings.gradle 增加
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_test_module\\.android\\include_flutter.groovy'
))
基礎(chǔ)框架就搭建成功了
Demo 實(shí)現(xiàn)
最上層放置了一個(gè) Android原生 TextView 下方使用的FlutterView
flutterView = Flutter.createView(this, getLifecycle(), "route2");
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
frameLayout.addView(flutterView, layoutParams);
其中 flutterView = Flutter.createView(this, getLifecycle(), "route2"); route2 與flutter_test_module lib 文件夾下 main.dart 中 所對(duì)應(yīng) 希望加載 哪個(gè)頁(yè)面 就填寫相應(yīng)的 route 名稱.
Widget _widgetForRoute(String route) {
switch (route) {
case 'route1':
return MyHomePage(title: 'Flutter Demo Home Page1');
case 'route2':
return MyHomePage(title: 'Flutter Demo Home Page2');
default:
return MyHomePage(title: 'Flutter Demo Home Page2');
}
}
Flutter 調(diào)用Android
java
new MethodChannel(flutterView, FlutterToAndroidCHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
//接收來(lái)自flutter的指令withoutParams
if (methodCall.method.equals("withoutParams")) {
//跳轉(zhuǎn)到指定Activity
Intent intent = new Intent(NativeActivity.this, NativeActivity.class);
startActivity(intent);
//返回給flutter的參數(shù)
result.success("success");
}
//接收來(lái)自flutter的指令withParams
else if (methodCall.method.equals("withParams")) {
//解析參數(shù)
String text = methodCall.argument("flutter");
//帶參數(shù)跳轉(zhuǎn)到指定Activity
Intent intent = new Intent(NativeActivity.this, NativeActivity.class);
intent.putExtra("test", text);
startActivity(intent);
//返回給flutter的參數(shù)
result.success("success");
} else {
result.notImplemented();
}
}
});
dart
Future<Null> _jumpToNative() async {
String result = await toAndroidPlugin.invokeMethod('withoutParams');
print(result);
}
Future<Null> _jumpToNativeWithParams() async {
Map<String, String> map = { "flutter": "這是一條來(lái)自flutter的參數(shù)" };
String result = await toAndroidPlugin.invokeMethod('withParams', map);
print(result);
}
Android 向 Flutter 傳參
java
new EventChannel(flutterView, AndroidToFlutterCHANNEL)
.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
String androidParmas = "來(lái)自android原生的參數(shù)";
eventSink.success(androidParmas);
}
@Override
public void onCancel(Object o) {
}
});
dart
void _startfromAndroiPlugin(){
if(_fromAndroiSub == null){
_fromAndroiSub = fromAndroiPlugin.receiveBroadcastStream()
.listen(_onfromAndroiEvent,onError: _onfromAndroiError);
}
}
void _onfromAndroiEvent(Object event) {
setState(() {
_nativeParams = event;
});
}
void _onfromAndroiError(Object error) {
setState(() {
_nativeParams = "error";
print(error);
});
}
有幾處 要注意一一對(duì)應(yīng)
new EventChannel(flutterView, AndroidToFlutterCHANNEL)
new MethodChannel(flutterView, FlutterToAndroidCHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
//接收來(lái)自flutter的指令withoutParams
if (methodCall.method.equals("withoutParams")) {
//跳轉(zhuǎn)到指定Activity
Intent intent = new Intent(NativeActivity.this, NativeActivity.class);
startActivity(intent);
//返回給flutter的參數(shù)
result.success("success");
}
//接收來(lái)自flutter的指令withParams
else if (methodCall.method.equals("withParams")) {
//解析參數(shù)
String text = methodCall.argument("flutter");
//帶參數(shù)跳轉(zhuǎn)到指定Activity
Intent intent = new Intent(NativeActivity.this, NativeActivity.class);
intent.putExtra("test", text);
startActivity(intent);
//返回給flutter的參數(shù)
result.success("success");
} else {
result.notImplemented();
}
}
});
dart
Future<Null> _jumpToNative() async {
String result = await toAndroidPlugin.invokeMethod('withoutParams');
print(result);
}
Future<Null> _jumpToNativeWithParams() async {
Map<String, String> map = { "flutter": "這是一條來(lái)自flutter的參數(shù)" };
String result = await toAndroidPlugin.invokeMethod('withParams', map);
print(result);
}
Android 向 Flutter 傳參
java
new EventChannel(flutterView, AndroidToFlutterCHANNEL)
.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
String androidParmas = "來(lái)自android原生的參數(shù)";
eventSink.success(androidParmas);
}
@Override
public void onCancel(Object o) {
}
});
dart
void _startfromAndroiPlugin(){
if(_fromAndroiSub == null){
_fromAndroiSub = fromAndroiPlugin.receiveBroadcastStream()
.listen(_onfromAndroiEvent,onError: _onfromAndroiError);
}
}
void _onfromAndroiEvent(Object event) {
setState(() {
_nativeParams = event;
});
}
void _onfromAndroiError(Object error) {
setState(() {
_nativeParams = "error";
print(error);
});
}
有幾處 要注意一一對(duì)應(yīng)
public static final String FlutterToAndroidCHANNEL = "com.litngzhe.toandroid/plugin";
public static final String AndroidToFlutterCHANNEL= "com.litngzhe.toflutter/plugin";
new EventChannel(flutterView, AndroidToFlutterCHANNEL)
new MethodChannel(flutterView, FlutterToAndroidCHANNEL)
dart中
//獲取到插件與原生的交互通道
static const toAndroidPlugin = const MethodChannel('com.litngzhe.toandroid/plugin');
static const fromAndroiPlugin = const EventChannel('com.litngzhe.toflutter/plugin');
MethodChannel 中 涉及到的方法名要要統(tǒng)一
Flutter 布局及路由導(dǎo)航
可以看 胖哥視頻
http://jspang.com/post/flutter4.html
本文中 知識(shí)點(diǎn) 從下方文章學(xué)習(xí)
http://www.reibang.com/p/c5263a3d7aac
本文demo 傳至 Github
下載地址
github 上有反饋說(shuō) demo 無(wú)法運(yùn)行.兩個(gè)項(xiàng)目 要分開打開. 先把 moudle 打開,
解決 庫(kù)依賴問(wèn)題 運(yùn)行編譯.
flutter_test_module 先運(yùn)行
或者 在終端 輸入 flutter packages get
程序不報(bào)錯(cuò)后
目錄中出現(xiàn) android 及IOS環(huán)境
點(diǎn)擊運(yùn)行 .
打開 FlutterTest
點(diǎn)擊運(yùn)行.