一佳谦、背景
近期在做Android項目轉(zhuǎn)型為Flutter凤壁,在轉(zhuǎn)型的過程中,我們選擇的是各業(yè)務(wù)模塊逐各替換的方式膘掰。這種方式下必然會涉及到Android與Flutter的交互章姓,而阿里提供的flutter_boost就是交互之作。
二、demo介紹
github:https://github.com/zbyJade/AndroidWithFlutter.git
如果下載后請進行如下操作
如果還報錯請重啟
功能介紹:
- Android原生界面跳轉(zhuǎn)Flutter界面凡伊,并傳參
- Flutter界面跳轉(zhuǎn)Android原生界面零渐,并傳參
-
Android和Flutter在同一界面顯示
三、創(chuàng)建flutter_module
1.為了使demo代碼簡潔系忙,新建一個Android工程诵盼,我用的是AS 3.6.3
2.新建flutter module
Project location 建議選擇到你的Android project下,這樣較清晰
3.添加配置(AS 3.6會自動生成)
Project Settings
evaluate(new File(
settingsDir,
'flutter_module/.android/include_flutter.groovy'
))
include ':flutter_module'
app build.grade
implementation project(path: ':flutter')
4.創(chuàng)建module后银还,產(chǎn)生的問題和解決辦法(如果沒有出現(xiàn)更好)
問題1:該Wring可忽略
問題2:
定位到問題文件拦耐,可刪除框內(nèi)文件
四、依賴flutter_boost
如果你使用了Androidx找到兼容的版本
添加flutter_boost最新依賴
實現(xiàn)過程如下
flutter_boost: ^1.12.13+1
如果要是沒有出現(xiàn)flutter和flutter_boost的module就稍微等一會
添加module
五见剩、使用flutter_boost
5.1 封裝PageRouter,界面跳轉(zhuǎn)的路由工具類
public class PageRouter {
// 界面格式可自定義
public final static String OnePageUrl = "url://onePage";
public final static String NativePage = "url://nativePage";
public final static Map<String, String> pageName = new HashMap<String, String>() {{
put(OnePageUrl, "onePage");
}};
public static boolean openPageByUrl(Context context, String url, Map params) {
return openPageByUrl(context, url, params, 0);
}
public static boolean openPageByUrl(Context context, String url, Map params, int requestCode) {
String flutterPage = null;
if (url.startsWith(OnePageUrl)) {
flutterPage = pageName.get(OnePageUrl);
Intent intent = BoostFlutterActivity.withNewEngine().url(flutterPage).params(params)
.backgroundMode(BoostFlutterActivity.BackgroundMode.opaque).build(context);
context.startActivity(intent);
return true;
} else if (url.startsWith(NativePage)) {
String aNative = (String) params.get("native");
Bundle bundle = new Bundle();
bundle.putString("native", aNative);
context.startActivity(new Intent(context, NativePageActivity.class).putExtras(bundle));
return true;
}
return false;
}
}
5.2 Application中初始化(記著在AndroidManifest里引入BaseApplication)
public class BaseApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化
initFlutterBoost();
}
private void initFlutterBoost() {
Platform platform = new FlutterBoost.ConfigBuilder(this, new INativeRouter(){
@Override
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
String assembleUrl = Utils.assembleUrl(url, urlParams);
PageRouter.openPageByUrl(context, assembleUrl, urlParams);
}
}).isDebug(true)
.whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
.build();
FlutterBoost.instance().init(platform);
}
}
5.3 聲明BoostFlutterActivity
<!-- 聲明加載flutter界面的activity-->
<activity
android:name="com.idlefish.flutterboost.containers.BoostFlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:theme="@style/Theme.AppCompat"
android:windowSoftInputMode="adjustResize">
<!--添加loading-->
<!--如果不添加meta-data會出現(xiàn)黑色閃屏-->
<!--如果只添加name扫俺,不添加resource會運行不起來-->
<!--resource需設(shè)置一個loading圖片-->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/svg_loading_page" />
</activity>
5.4 activity跳轉(zhuǎn)flutter界面苍苞,并傳遞參數(shù)
findViewById(R.id.bt1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 將map傳遞到flutter界面
HashMap<String, String> params = new HashMap<>();
params.put("OneKey","從Android跳轉(zhuǎn)到Flutter界面");
PageRouter.openPageByUrl(MainActivity.this, PageRouter.OnePageUrl, params);
}
});
5.5 flutter界面跳轉(zhuǎn)activity,并傳遞參數(shù)
children: <Widget>[
// 如果接收到參數(shù)則顯示狼纬,OneKey為傳遞map中的key
Text(widget.param == null ? "未接收到參數(shù)" : widget.param["OneKey"]),
RaisedButton(
child: Text("調(diào)回Android界面"),
onPressed: () {
// url://nativePage為PageRouter界面定義的羹呵,flutter調(diào)起Android界面
FlutterBoost.singleton.open("url://nativePage",
urlParams: {"native": "我是參數(shù)乙"});
}),
RaisedButton(
child: Text("關(guān)閉當前界面"),
onPressed: () {
Navigator.of(context).pop();
}),
],
5.6 Android和flutter混合界面
public class NativeAndFlutterActivity extends AppCompatActivity implements SplashScreenProvider {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_native_and_flutter);
// 將flutter界面作為fragment添加到FrameLayout上
FlutterFragment mFragment = new FlutterFragment.NewEngineFragmentBuilder().url("fragmentPage").build();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_stub, mFragment)
.commit();
}
@Override
public SplashScreen provideSplashScreen() {
// 為顯示加載loading
Drawable manifestSplashDrawable = getSplashScreenFromManifest();
if (manifestSplashDrawable != null) {
return new DrawableSplashScreen(manifestSplashDrawable, ImageView.ScaleType.CENTER, 500L);
} else {
return null;
}
}
protected static final String SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable";
private Drawable getSplashScreenFromManifest() {
try {
@SuppressLint("WrongConstant") ActivityInfo activityInfo = getPackageManager().getActivityInfo(
getComponentName(),
PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES
);
Bundle metadata = activityInfo.metaData;
Integer splashScreenId = metadata != null ? metadata.getInt(SPLASH_SCREEN_META_DATA_KEY) : null;
return splashScreenId != null
? Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP
? getResources().getDrawable(splashScreenId, getTheme())
: getResources().getDrawable(splashScreenId)
: null;
} catch (PackageManager.NameNotFoundException e) {
// This is never expected to happen.
return null;
}
}
}
結(jié)尾
本篇文章僅介紹了flutter_boost的基礎(chǔ)使用。更加詳細的demo 代碼請到github上下載疗琉。希望對讀者flutter學習過程有所幫助冈欢。