In this example we are going to create the "most classical" Flutter application: the counter app.
We will define a PlatformService called CounterService that will provide three PlatformOperations:
- public int GetValue() → Called when Flutter requests the current counter value;
- public int Increment() → Called when Flutter requests to increment the counter: the updated value will be returned;
- public int Decrement() → Called when Flutter requests to decrement the counter: the updated value will be returned.
Create the project
Create a project named "FlutnetCounter" using the Flutnet Console.
The generated project structure will contain the Visual Studio solution (FlutnetCounter.sln) and a set of Xamarin and Flutter projects:
- Xamarin
- FlutnetCounter.Android (Xamarin.Android application)
- FlutnetCounter.iOS (Xamarin.iOS application)
- FlutnetCounter.ServiceLibrary (.NET Standard class library)
- Flutter
- flutnet_counter (Flutter module → it's the main Flutter project where you develop the UI)
- flutnet_counter_bridge (Flutter package → it will contain auto-generated Dart code that defines the communication layer between Flutter and Xamarin).
Define the PlatformService
![](../../portals/0/Images/Docs/flutnet_project_selection_servicelibrary_500px-1.jpg)
In the *.ServiceLibrary project we'll add a new class, CounterService.cs: this will be our PlatformService. Here's a basic implementation according to what we discussed above:
CounterService.cs
using Flutnet.ServiceModel;
namespace FlutnetCounter.ServiceLibrary
{
// This service class will be exposed to Flutter
[PlatformService]
public class CounterService
{
// Current state
private int _value = 0;
[PlatformOperation]
public int GetValue()
{
return _value;
}
[PlatformOperation]
public int Increment()
{
_value++;
return _value;
}
[PlatformOperation]
public int Decrement()
{
_value--;
return _value;
}
}
}
Build ServiceLibrary project
![](../../portals/0/Images/Docs/flutnet_project_selection_servicelibrary_bridge_500px-1.jpg)
By default the ServiceLibrary project is configured to execute the $ flutnet pack command in the post-build event.
The procedure will update the "flutnet_counter_bridge" package with all the required Dart code for managing the communication between Flutter and Xamarin.
Configure the FlutnetBridge Mode
![](../../portals/0/Images/Docs/flutnet_project_selection_android_ios_flutter_500px-1.jpg)
Depending on your development preferences, you could use a specific FlutnetBridge mode:
In order to set the FlutnetBridge mode, just edit the following methods:
- App.cs → ConfigureFlutnetBridge(FlutterEngine) in Xamarin.Android app
- ViewController → ViewDidAppear(bool) in Xamarin.iOS app
- main.dart → main() in Flutter module
Xamarin.Android
App.cs → ConfigureFlutnetBridge(FlutterEngine)
#if (DEBUG)
_bridge = new FlutnetBridge(flutterEngine, AppContext, FlutnetBridgeMode.PlatformChannel);
#else
...
#endif
Xamarin.iOS
ViewController.cs → ViewDidAppear(bool)
#if (DEBUG)
_bridge = new FlutnetBridge(this.Engine, FlutnetBridgeMode.PlatformChannel);
#else
...
#endif
Flutter
main.dart
import 'package:flutter/material.dart';
import 'package:flutnet_counter_bridge
/flutnet_bridge.dart';
void main() {
// Configure the bridge mode for debug
FlutnetBridgeConfig.mode = FlutnetBridgeMode.PlatformChannel;
runApp(MyApp());
}
Develop your user interface in Flutter
![](../../portals/0/Images/Docs/flutnet_project_selection_flutter_500px-1.jpg)
// Import the counter service
import 'package:flutnet_counter_bridge
/flutnet_counter/service_library/counter_service.dart';
...
class _MyHomePageState extends State<MyHomePage> {
// Reference to the xamarin counter service: instaceID is "counter_service"
final CounterService _counterService = CounterService("counter_service");
// The current counter value
int _counterValue = -1;
void _load() async {
// Get the value from xamarin
int value = await _counterService.getValue();
setState(() {
_counterValue = value;
});
}
void _increment() async {
// Increment the value from xamarin
int value = await _counterService.increment();
setState(() {
_counterValue = value;
});
}
void _decrement() async {
// Decrement the value from xamarin
int value = await _counterService.decrement();
setState(() {
_counterValue = value;
});
}
....
Build the Flutter project
![](../../portals/0/Images/Docs/flutnet_project_selection_flutter_build_500px-1.jpg)
Before running the Xamarin app, you need to build your Flutter module project ("flutnet_counter" in our case).
In order to do this, open the terminal from Visual Studio Code and run the following commands:
- $ flutter build aar --no-profile
- $ flutter build ios-framework --no-profile (only if you're on macOS)
Once the build is finished, you should be able to run your Xamarin app with Flutter as user interface.
Register the PlatformService
![](../../portals/0/Images/Docs/flutnet_project_selection_android_ios_500px-1.jpg)
In order to expose the service to Flutter, you need to register an instance of this service on the FlutnetRuntime by specifying a proper, unique name ("counter_service" in this case).
The registration must be done before the FlutnetBridge initialization. This occurs in the following methods:
- App → ConfigureFlutnetRuntime() in Xamarin.Android app
- ViewController → ViewDidAppear(bool) in Xamarin.iOS app
// Initialize the Flutnet environment
FlutnetRuntime.Init();
// Register the service
FlutnetRuntime.RegisterPlatformService(new CounterService(), "counter_service");
...