Flutter Module in Android App
Today I’m going to import a Flutter module into an existing Android app. Moreover, I’ll call native methods from that Flutter screen. Because I solved the issue which I mentioned in the last paragraph of my previous story, thanks to Muhannad Fakhouri.
I created a basic Android app and imported a Flutter module. By the FloatingActionButton, I’m starting the FlutterActivity with a route and put a parameter for the title to handle on the Dart side.
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(
new FlutterActivity
.NewEngineIntentBuilder(MyFlutterActivity.class)
.initialRoute("/second")
.build(getApplicationContext())
.putExtra("title", "Title")
);
}
});
I located MyFlutterActivity.java on the same folder as other java classes and defined the activity in Manifest.xml.
<activity android:name=".MyFlutterActivity"
android:theme="@style/AppTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
Then, I override the onCreate method of MyFlutterActivity to get the title parameter and set it to a global variable:
String title = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
title = extras.getString("title");
}
And override the configureFlutterEngine to handle the method calls from the Dart side of the app.
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL).setMethodCallHandler(((methodCall, result) -> {
if (methodCall.method.equals("getBatteryLevel")) {
result.success("batteryLevel");
} else if (methodCall.method.equals("getTitle")) {
result.success(title); // It returns "Title".
} else {
result.notImplemented();
}
}));
}
Now, I can easily call the related invokeMethod in the initState of SecondScreen.dart to get the title that passed as an argument from the native side.
@override
void initState() {
super.initState();
getTitle();
}
getTitle() async {
String res = await platformMethodChannel.invokeMethod('getTitle');
setState(() {
title = res;
});
}
Voila! The parameter “Title” is on the screen.
And I can invoke the other methods like getBatteryLevel in this Flutter screen.
void _incrementCounter() async {
try {
String response =
await platformMethodChannel.invokeMethod('getBatteryLevel');
print(response);
setState(() {
title = response;
});
} on PlatformException catch (e) {
print("e.message");
print(e.message);
}
setState(() {
_counter++;
});
}
The parameter has changed as demonstrated below.
You can access the GitHub repo about this story from here: