Add a Flutter screen to an Android app
This guide describes how to add a single Flutter screen to an existing Android app. A Flutter screen can be added as a normal, opaque screen, or as a see-through, translucent screen. Both options are described in this guide.
Add a normal Flutter screen
#
                Step 1: Add FlutterActivity to AndroidManifest.xml
#
                  Flutter provides FlutterActivity
                   to display a Flutter
                  experience within an Android app. Like any other Activity,
                  FlutterActivity must be registered in your
                  AndroidManifest.xml. Add the following XML to your
                  AndroidManifest.xml file under your application tag:
                
<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"
  />
                    
                    
                    
                  
                  The reference to @style/LaunchTheme can be replaced
                  by any Android theme that want to apply to your FlutterActivity.
                  The choice of theme dictates the colors applied to
                  Android's system chrome, like Android's navigation bar, and to
                  the background color of the FlutterActivity just before
                  the Flutter UI renders itself for the first time.
                
Step 2: Launch FlutterActivity
#
                  With FlutterActivity registered in your manifest file,
                  add code to launch FlutterActivity from whatever point
                  in your app that you'd like. The following example shows
                  FlutterActivity being launched from an OnClickListener.
                
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)
    );
  }
});
                          
                          
                          
                        
                  The previous example assumes that your Dart entrypoint
                  is called main(), and your initial Flutter route is '/'.
                  The Dart entrypoint can't be changed using Intent,
                  but the initial route can be changed using Intent.
                  The following example demonstrates how to launch a
                  FlutterActivity that initially renders a custom
                  route in 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)
      );
  }
});
                          
                          
                          
                        Replace "/my_route" with your desired initial route.
                  The use of the withNewEngine() factory method
                  configures a FlutterActivity that internally create
                  its own FlutterEngine
                   instance. This comes with a
                  non-trivial initialization time. The alternative approach
                  is to instruct FlutterActivity to use a pre-warmed,
                  cached FlutterEngine, which minimizes Flutter's
                  initialization time. That approach is discussed next.
                
Step 3: (Optional) Use a cached FlutterEngine
#
                  Every FlutterActivity creates its own FlutterEngine
                  by default. Each FlutterEngine has a non-trivial
                  warm-up time. This means that launching a standard
                  FlutterActivity comes with a brief delay before your Flutter
                  experience becomes visible. To minimize this delay,
                  you can warm up a FlutterEngine before arriving at
                  your FlutterActivity, and then you can use
                  your pre-warmed FlutterEngine instead.
                
                  To pre-warm a FlutterEngine, find a reasonable
                  location in your app to instantiate a FlutterEngine.
                  The following example arbitrarily pre-warms a
                  FlutterEngine in the Application class:
                
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);
  }
}
                          
                          
                          
                        
                  The ID passed to the FlutterEngineCache
                   can be whatever you want.
                  Make sure that you pass the same ID to any FlutterActivity
                  or FlutterFragment
                   that should use the cached FlutterEngine.
                  Using FlutterActivity with a cached FlutterEngine
                  is discussed next.
                
                  With a pre-warmed, cached FlutterEngine, you now need
                  to instruct your FlutterActivity to use the cached
                  FlutterEngine instead of creating a new one.
                  To accomplish this, use FlutterActivity's 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)
      );
  }
});
                          
                          
                          
                        
                  When using the withCachedEngine() factory method,
                  pass the same ID that you used when caching the desired
                  FlutterEngine.
                
                  Now, when you launch FlutterActivity,
                  there is significantly less delay in
                  the display of Flutter content.
                
Initial route with a cached engine
#
                  The concept of an initial route is available when configuring a
                  FlutterActivity or a FlutterFragment with a new FlutterEngine.
                  However, FlutterActivity and FlutterFragment don't offer the
                  concept of an initial route when using a cached engine.
                  This is because a cached engine is expected to already be
                  running Dart code, which means it's too late to configure the
                  initial route.
                
                  Developers that would like their cached engine to begin
                  with a custom initial route can configure their cached
                  FlutterEngine to use a custom initial route just before
                  executing the Dart entrypoint. The following example
                  demonstrates the use of an initial route with a cached engine:
                
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);
  }
}
                          
                          
                          
                        
                  By setting the initial route of the navigation channel, the associated
                  FlutterEngine displays the desired route upon initial execution of the
                  runApp() Dart function.
                
                  Changing the initial route property of the navigation channel
                  after the initial execution of runApp() has no effect.
                  Developers who would like to use the same FlutterEngine
                  between different Activitys and Fragments and switch
                  the route between those displays need to set up a method channel and
                  explicitly instruct their Dart code to change Navigator routes.
                
Add a translucent Flutter screen
#
                
                  Most full-screen Flutter experiences are opaque.
                  However, some apps would like to deploy a Flutter
                  screen that looks like a modal, for example,
                  a dialog or bottom sheet. Flutter supports translucent
                  FlutterActivitys out of the box.
                
                  To make your FlutterActivity translucent,
                  make the following changes to the regular process of
                  creating and launching a FlutterActivity.
                
Step 1: Use a theme with translucency
#
                  Android requires a special theme property for Activitys that render
                  with a translucent background. Create or update an Android theme with the
                  following property:
                
<style name="MyTheme" parent="@style/MyParentTheme">
  <item name="android:windowIsTranslucent">true</item>
</style>
                    
                    
                    
                  Then, apply the translucent theme to your 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"
  />
                    
                    
                    
                  
                  Your FlutterActivity now supports translucency.
                  Next, you need to launch your FlutterActivity
                  with explicit transparency support.
                
Step 2: Start FlutterActivity with transparency
#
                  To launch your FlutterActivity with a transparent background,
                  pass the appropriate BackgroundMode to the 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)
);
                          
                          
                          
                        You now have a FlutterActivity with a transparent background.
Unless stated otherwise, the documentation on this site reflects Flutter 3.35.5. Page last updated on 2025-10-28. View source or report an issue.