在 Android 應用程式中加入 Flutter 螢幕
學習如何在現有的 Android 應用程式中加入單一 Flutter 螢幕。
本指南說明如何在現有的 Android 應用程式中加入單一 Flutter 螢幕。Flutter 螢幕可以作為一般、不透明的螢幕加入,也可以作為可透視的半透明螢幕加入。本指南將說明這兩種方式。
加入一般 Flutter 螢幕
#
步驟 1:在 AndroidManifest.xml 中加入 FlutterActivity
#
Flutter 提供了 FlutterActivity,可在 Android 應用程式中顯示 Flutter 體驗。和其他
Activity 一樣,FlutterActivity
必須註冊在你的 AndroidManifest.xml 中。請在 AndroidManifest.xml 檔案的 application
標籤下方加入以下 XML:
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
@style/LaunchTheme 的參考可以替換為任何你想要套用到 FlutterActivity 的 Android 主題(theme)。
主題的選擇會決定應用於 Android 系統 chrome(如 Android 導覽列)的顏色,以及在 Flutter UI 首次渲染前,FlutterActivity
的背景顏色。
步驟 2:啟動 FlutterActivity
#
在你的 manifest 檔案中註冊好 FlutterActivity 之後,
你可以在應用程式中任何你想要的地方,加入程式碼來啟動 FlutterActivity。以下範例展示了
從 OnClickListener 啟動 FlutterActivity 的方式。
MyButton(onClick = {
startActivity(
FlutterActivity.createDefaultIntent(this)
)
})
@Composable
fun MyButton(onClick: () -> Unit) {
Button(onClick = onClick) {
Text("Launch Flutter!")
}
}
myButton.setOnClickListener {
startActivity(
FlutterActivity.createDefaultIntent(this)
)
}
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity.createDefaultIntent(currentActivity)
);
}
});
前述範例假設你的 Dart 進入點(entrypoint)為 main(),且初始的 Flutter 路由為 /。Dart 進入點無法透過 Intent
進行變更,但初始路由可以使用 Intent 來修改。以下範例說明如何啟動一個 FlutterActivity,並在 Flutter 中初始渲染自訂路由。
MyButton(onClick = {
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("/my_route")
.build(this)
)
})
@Composable
fun MyButton(onClick: () -> Unit) {
Button(onClick = onClick) {
Text("Launch Flutter!")
}
}
myButton.setOnClickListener {
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("/my_route")
.build(this)
)
}
myButton.addOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("/my_route")
.build(currentActivity)
);
}
});
將 "/my_route" 替換為你想要的初始路由。
使用 withNewEngine() 工廠方法會設定一個 FlutterActivity,該物件會在內部自行建立一個 FlutterEngine
實例。這樣會帶來不小的初始化時間。另一種做法是指示 FlutterActivity 使用預先加載並快取的 FlutterEngine,這樣可以將 Flutter 的初始化時間降到最低。接下來將說明這種做法。
步驟 3:(選用)使用快取的 FlutterEngine
#
每個 FlutterActivity 預設都會建立自己的 FlutterEngine。每個 FlutterEngine 都需要一定的預熱時間。這表示啟動標準的
FlutterActivity 時,在你的 Flutter 體驗顯示出來前會有短暫的延遲。為了減少這個延遲,你可以在進入 FlutterActivity
之前先預熱一個 FlutterEngine,然後直接使用這個預熱好的 FlutterEngine。
要預熱一個 FlutterEngine,請在你的應用程式中找到合適的位置來實例化 FlutterEngine。以下範例會在 Application
類別中隨機預熱一個 FlutterEngine:
class MyApplication : Application() {
lateinit var flutterEngine : FlutterEngine
override fun onCreate() {
super.onCreate()
// Instantiate a FlutterEngine.
flutterEngine = FlutterEngine(this)
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
// Cache the FlutterEngine to be used by FlutterActivity.
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine)
}
}
public class MyApplication extends Application {
public FlutterEngine flutterEngine;
@Override
public void onCreate() {
super.onCreate();
// Instantiate a FlutterEngine.
flutterEngine = new FlutterEngine(this);
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartEntrypoint.createDefault()
);
// Cache the FlutterEngine to be used by FlutterActivity.
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
}
}
傳遞給 FlutterEngineCache
的 ID 可以是任何你想要的值。
請確保你在任何需要使用快取 FlutterEngine 的 FlutterActivity
或 FlutterFragment
中傳遞相同的 ID。
接下來會說明如何將 FlutterActivity 與已快取的 FlutterEngine 搭配使用。
有了預先啟動並快取的 FlutterEngine 之後,你現在需要
指示你的 FlutterActivity 使用這個快取的
FlutterEngine,而不是建立新的實例。
為了達成這個目的,請使用 FlutterActivity 的 withCachedEngine()
builder:
myButton.setOnClickListener {
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(this)
)
}
myButton.addOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(currentActivity)
);
}
});
當你使用 withCachedEngine() 工廠方法時,
請傳入你在快取目標 FlutterEngine 時所使用的相同 ID。
現在,當你啟動 FlutterActivity 時,
顯示 Flutter 內容的延遲會大幅減少。
使用已快取 engine 設定初始路由
#
初始路由的概念可在使用新的 FlutterEngine 設定 FlutterActivity 或 FlutterFragment
時使用。
然而,使用快取引擎時,FlutterActivity 與 FlutterFragment 並不提供初始路由的概念。
這是因為快取引擎預期已在執行 Dart 程式碼,這表示此時已來不及設定初始路由。
希望快取引擎以自訂初始路由啟動的開發者,可以在執行 Dart 進入點之前,設定快取的 FlutterEngine 使用自訂初始路由。以下範例示範如何在快取引擎中使用初始路由:
class MyApplication : Application() {
lateinit var flutterEngine : FlutterEngine
override fun onCreate() {
super.onCreate()
// Instantiate a FlutterEngine.
flutterEngine = FlutterEngine(this)
// Configure an initial route.
flutterEngine.navigationChannel.setInitialRoute("your/route/here");
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
// Cache the FlutterEngine to be used by FlutterActivity or FlutterFragment.
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine)
}
}
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Instantiate a FlutterEngine.
flutterEngine = new FlutterEngine(this);
// Configure an initial route.
flutterEngine.getNavigationChannel().setInitialRoute("your/route/here");
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartEntrypoint.createDefault()
);
// Cache the FlutterEngine to be used by FlutterActivity or FlutterFragment.
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
}
}
透過設定導航頻道的初始路由,相關聯的 FlutterEngine 將在初次執行 runApp() Dart 函式時顯示所需的路由。
在 runApp() 初次執行後再變更導航頻道的初始路由屬性將不會有任何效果。
希望在不同 Activity 與 Fragment 之間共用相同 FlutterEngine
並在這些畫面之間切換路由的開發者,需要設定方法頻道,並明確指示其 Dart 程式碼變更 Navigator 路由。
新增半透明的 Flutter 螢幕
#
大多數全螢幕的 Flutter 體驗都是不透明的。
然而,有些應用程式希望部署看起來像模態視窗(modal)的 Flutter 螢幕,
例如對話框(dialog)或底部彈出視窗(bottom sheet)。
Flutter 原生支援半透明的 FlutterActivity。
若要讓你的 FlutterActivity 具有半透明效果,
請在建立與啟動 FlutterActivity 的一般流程中進行以下修改。
步驟 1:使用具有半透明屬性的主題
#
Android 要求具有半透明背景的 Activity 必須指定特殊的主題屬性。
請建立或更新一個 Android 主題,並加入以下屬性:
<style name="MyTheme" parent="@style/MyParentTheme">
<item name="android:windowIsTranslucent">true</item>
</style>
然後,將半透明主題(translucent theme)套用到你的 FlutterActivity。
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/MyTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
你的 FlutterActivity 現在已支援透明度(translucency)。
接下來,你需要以明確支援透明度的方式啟動你的 FlutterActivity。
步驟 2:以透明背景啟動 FlutterActivity
#
若要以透明背景啟動你的 FlutterActivity,
請將適當的 BackgroundMode 傳遞給 IntentBuilder:
// Using a new FlutterEngine.
startActivity(
FlutterActivity
.withNewEngine()
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.build(this)
);
// Using a cached FlutterEngine.
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.build(this)
);
// Using a new FlutterEngine.
startActivity(
FlutterActivity
.withNewEngine()
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.build(context)
);
// Using a cached FlutterEngine.
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.build(context)
);
你現在已經擁有一個具有透明背景的 FlutterActivity。
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-06-14. View source or report an issue.