Adding to existing app - flutter-tizen/flutter-tizen GitHub Wiki

You don't have to rewrite your existing Tizen app in Flutter all at once. Flutter can partially be integrated into your Tizen app as a module.

Note: Although the target app can be either an EFL (C++/C#) or NUI (C#) app, EFL is not actively being maintained by the code owner and will be deprecated in the future. If your app is based on EFL, we recommend migrating the entire app to either NUI or Flutter. In this document, an NUI app will be used as an example.

Note: The target API version of the app must be 6.5 or higher.

Note: This feature is currently under testing and not generally recommended for production use.

Creating a Flutter module

Let's assume that you have an existing Tizen app at some/path/MyApp, and you want to create a Flutter module project next to the directory.

$ cd some/path
$ flutter-tizen create -t module my_flutter

This creates a directory called my_flutter with some Dart code to get you started and a hidden .tizen directory. The .tizen directory contains a Tizen project that helps you run a barebones standalone version of the module via flutter-tizen run.

To allow your Tizen app to reference the module, the module needs to be built once. The following command will compile the module's Dart code and generate output artifacts in my_flutter/build/tizen/module.

$ cd my_flutter
$ flutter-tizen build module --device-profile tv

You can customize the command line arguments as you need (see flutter-tizen build module -h for details). For example, if you want to launch the app on an emulator rather than a physical device, you need to provide --debug --target-arch x86.

Adding the module as a dependency

To let your app depend on the module created in the above (my_flutter/build/tizen/module), you need to add the following lines to the app's .csproj file.

<PropertyGroup>
  <FlutterModuleDir>../my_flutter/build/tizen/module</FlutterModuleDir>
</PropertyGroup>

<ItemGroup>
  <PackageReference Include="Tizen.Flutter.Embedding" Version="1.0.0"/>
</ItemGroup>

Make sure to replace 1.0.0 with the latest version of the nuget package available at nuget.org.

Adding a Flutter view

Once you have added the Flutter module as a dependency, the last thing you have to do is to add an NUIFlutterView (or ElmFlutterView) instance to the app's view hierarchy. Here's a full example.

using Tizen.Flutter.Embedding;
using Tizen.NUI;
using Tizen.NUI.BaseComponents;

class App : NUIApplication
{
    NUIFlutterView flutterView;

    protected override void OnCreate()
    {
        base.OnCreate();

        // Create an instance of NUIFlutterView.
        flutterView = new NUIFlutterView()
        {
            WidthSpecification = LayoutParamPolicies.MatchParent,
            HeightSpecification = LayoutParamPolicies.MatchParent,
        };

        // Start running the module's Dart code.
        if (flutterView.RunEngine())
        {
            // Register C++ plugins if any.
            GeneratedPluginRegistrant.RegisterPlugins(flutterView.Engine);

            // Add the view to the parent container.
            Window.Instance.GetDefaultLayer().Add(flutterView);
        }
    }

    protected override void OnTerminate()
    {
        base.OnTerminate();

        if (flutterView != null)
        {
            // The view must be explicitly destroyed if it's no longer used.
            flutterView.Destroy();
        }
    }

    static void Main(string[] args)
    {
        var app = new App();
        app.Run(args);
    }
}

The view can receive and handle user inputs (keyboard and pointer events) when it has a focus. The focus can be released by pressing the back key (when there's no route left in the navigation stack) or by explicitly calling SystemNavigator.pop.

Adding multiple Flutter views

You can add multiple Flutter views to a single app where each view runs its own Flutter engine individually. To allow each view to show different screens, you need to first create multiple entry points in the module's Dart code. An entry point is a function that takes no argument and is annotated with @pragma('vm:entry-point').

// "main" is always recognized as an entry point.
void main() {
  runApp(...);
}

@pragma('vm:entry-point')
void anotherMain() {
  runApp(...);
}

Then you can configure multiple instances of NUIFlutterView in the app code as follows.

// Run a Flutter view whose entry point is "main".
var flutterView1 = new NUIFlutterView()
{
    Size2D = new Size2D(600, 400),
};
if (flutterView1.RunEngine())
{
    GeneratedPluginRegistrant.RegisterPlugins(flutterView1.Engine);
    container.Add(flutterView1);
}

// Run another Flutter view whose entry point is "anotherMain".
var flutterView2 = new NUIFlutterView()
{
    Engine = new FlutterEngine("anotherMain"),
    Size2D = new Size2D(600, 400),
};
if (flutterView2.RunEngine())
{
    GeneratedPluginRegistrant.RegisterPlugins(flutterView2.Engine);
    container.Add(flutterView2);
}

Debugging

You can run your Flutter module as a standalone app using flutter-tizen run to use hot reload and any other DevTools features. For how to debug the app in VS Code, read Debugging apps.

If you want to debug a Flutter module running inside a Tizen app (not launched via flutter-tizen run), you need to first find the running Dart VM's observatory URI.

# For TV devices, use "sdb shell 0 showlog_level brief" instead.
$ sdb dlog ConsoleMessage
...
I/ConsoleMessage(26484): flutter: The Dart VM service is listening on http://127.0.0.1:41234/qTDzAbkqTvg=/

Then you can use the URI with flutter-tizen attach to connect to the running module.

$ cd some/path/my_flutter
$ flutter-tizen attach --debug-url http://127.0.0.1:41234/qTDzAbkqTvg=/

Limitations

Only C++ and Dart plugins can be used with Flutter modules. C# plugins are not supported as of now.

⚠️ **GitHub.com Fallback** ⚠️