1. Android 页面跳转到 Flutter 页面两种方式及传值
上一节看到无论跳转还是嵌入,速度都要一秒多,肉眼可见的慢,没有原生快很多。为了优化这个问题,flutter 提供了 FlutterEngine 来进行预热/缓存,需要跳转的时候直接找到对应 id 进行跳转即可。
1. Android 页面跳转到 Flutter 页面两种方式及传值
前面一节说了两种方式:
第一种作为 fragment 嵌入到原生页面中;
第二种是作为一个新的页面 activity 跳转进入;
下面讲的是用两种方法跳转到 flutter 然后传值。先看效果图:
对比上一节,跳转的速度快了很多,因为用到了 FlutterEngine ,它的简单使用:设置路由和传参,使用dart executor来预热,给它一个id并且缓存;
原生 Android 项目下具体代码如下:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.android.FlutterFragment;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
public class MainActivity extends AppCompatActivity {
Button tv_test,btn_test1;
FrameLayout frameFlutter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setFlutterEngine();
tv_test = findViewById(R.id.btn_test);
btn_test1 = findViewById(R.id.btn_test1);
frameFlutter = findViewById(R.id.frameFlutter);
tv_test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转activity
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(MainActivity.this)
);
}
});
btn_test1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//fragment嵌入
FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine_id")
.build();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.frameFlutter, flutterFragment)
.commit();
}
});
}
private void setFlutterEngine() {
// 初始化FlutterEngine.
FlutterEngine flutterEngine = new FlutterEngine(this);
//设置传参
flutterEngine.getNavigationChannel().setInitialRoute("route1?{\"name\":\"" + "张三" + "\"}");
// 使用dart executor来预热FlutterEngine.
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
);
// 缓存FlutterEngine,并且给一个id,方便后面获取
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
}
}
flutter module 中 main.dart ,取出对应路由,并且拿到传来的参数并且显示出来,具体代码:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'dart:convert';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _widgetForRoute(),// This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Widget _widgetForRoute() {
String route = _getRouteName(window.defaultRouteName);
Map<String, dynamic> params = _getParamsStr(window.defaultRouteName);
switch (route) {
case 'route1':
return Center(
child: Text(params['name']),
);
default:
return
Center(
child: Text(params['name']),
);
}
}
// 获取路由名称
String _getRouteName(String s) {
if (s.indexOf('?') == -1) {
return s;
} else {
return s.substring(0, s.indexOf('?'));
}
}
// 获取参数
Map<String, dynamic> _getParamsStr(String s) {
if (s.indexOf('?') == -1) {
return Map();
} else {
return json.decode(s.substring(s.indexOf('?') + 1));
}
}
这样就完成了跳转以及传参。