In this example we reproduce the old counter app, but listening the counter value changes from a PlatformEvent. The basic idea is that you can expose your C# events (EventHandler/ EventHandler<T>) to Flutter in form of Stream.
The code will be generated by the $ flutnet pack command. You only need to listen the event in Flutter and invoke the event in Xamarin. Flutnet will do the rest.
We will define a PlatformService called CounterService that will provide three PlatformOperation:
- public int GetValue ( ) → Flutter request the current counter value;
- public void Increment ( ) → Flutter request to increment the counter;
- public void Decrement ( ) → Flutter request to decrement the counter.
one PlatformEvent:
- public event EventHandler< CounterChangedArgs > ValueChanged
with one PlatformData:
- CounterChangedArgs.
Create the project
Create a project named "FlutnetEvents" using the Flutnet Console.
The generated project structure will contains the "FlutnetEvents" solution and all his related projects:
- Xamarin
- FlutnetEvents.Android
- FlutnetEvents.iOS
- FlutnetEvents.ServiceLibrary (net standard)
- Flutter
- flutnet_events (flutter module, where you develop the UI)
- flutnet_events_bridge (bridge package, genetared by the $ flutnet pack command)
Define the ServiceLibrary (PlatformService, Operations, etc...)
![](../../portals/0/Images/Docs/flutnet_project_selection_servicelibrary_500px-1.jpg)
CounterService.cs
using Flutnet.ServiceModel;
namespace FlutnetEvents.ServiceLibrary
{
// The event will contain the counter value updated
[PlatformData]
public class CounterChangedArgs : EventArgs
{
public int Value { get; set; }
}
// The counter service exposed to Flutter
[PlatformService]
public class CounterService
{
// The platform event exposed to Flutter
[ PlatformEvent ]
public event EventHandler<CounterChangedArgs> ValueChanged;
// Current state
private int _value = 0;
[PlatformOperation]
public int GetValue()
{
return _value;
}
[PlatformOperation]
public void Increment()
{
_value++;
// raise the event
OnValueChanged( new CounterChangedArgs()
{
Value = _value
});
}
[PlatformOperation]
public void Decrement()
{
_value--;
// raise the event
OnValueChanged(new CounterChangedArgs()
{
Value = _value
});
}
protected virtual void OnValueChanged(CounterChangedArgs e)
{
// all the connected handler receive the event (even in Flutter)
ValueChanged?.Invoke(this, e);
}
}
}
Build ServiceLibrary project → $ flutnet pack
![](../../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 generate all the required Flutter structure into the "flutnet_events_bridge" project.
Configure the FlutnetBridge Mode
![](../../portals/0/Images/Docs/flutnet_project_selection_android_ios_flutter_500px-1.jpg)
Based on your development preference you should use a specific FlutnetBridge mode:
The set the FlutnetBridge mode just edit the following files:
- MainApplication.cs → OnCreate() on Xamarin Android,
- ViewController.cs → ViewDidLoad() on Xamarin iOS,
- main.dart → main() on Flutter.
Flutter
main.dart
import 'package:flutter/material.dart';
import 'package:flutnet_events_bridge
/flutnet_bridge.dart';
void main() {
// Configure the bridge mode for debug
FlutnetBridgeConfig.mode = FlutnetBridgeMode.PlatformChannel;
runApp(MyApp());
}
Xamarin Android
App.cs → ConfigureFlutnetBridge(FlutterEngine flutterEngine)
#if (DEBUG)
_bridge = new FlutnetBridge(flutterEngine, this, FlutnetBridgeMode.PlatformChannel);
#else
.....
#endif
Xamarin iOS
ViewController.cs → ViewDidAppear(bool animated)
#if (DEBUG)
_bridge = new FlutnetBridge(flutterEngine, this, FlutnetBridgeMode.PlatformChannel);
#else
.....
#endif
Develop your user interface in Flutter
![](../../portals/0/Images/Docs/flutnet_project_selection_flutter_500px-1.jpg)
// Import the counter service
import 'package:flutnet_events_bridge
/flutnet_events/service_library/counter_service.dart';
import 'package:flutnet_events_bridge
/flutnet_events/service_library/counter_changed_args.dart';
....
class _MyHomePageState extends State<MyHomePage> {
// Reference to the xamarin counter service: instaceID is "counter_service"
final CounterService _counterService = CounterService("counter_service");
// The subscription to the event
StreamSubscription<CounterChangedArgs> _eventSubscription;
@override
void initState() {
super.initState();
_load();
// Connect to the counter changed event handler
_eventSubscription = _counterService.valueChanged.listen(
(CounterChangedArgs args) {
// When receive the event, refresh the label on screen
setState(() {
_counterValue = args.value;
});
},
cancelOnError: false,
);
}
@override
void dispose() {
// IMPORTANT: Cancel the subscription from the event.
_eventSubscription?.cancel();
super.dispose();
}
....
Build the Flutter project
![](../../portals/0/Images/Docs/flutnet_project_selection_flutter_build_500px-1.jpg)
Defore running the Xamarin app, you need build your Flutter module project ("flutnet_events" in our case).
To do so, you just open the terminal from visual studio code and run the command
- $ flutter build aar --no-profile for FlutnetEvents.Android,
- $ flutter build ios-framework --no-profile for FlutnetEvents.iOS ( ONLY on macOS ).
When the build finish you should be able to run your Xamarin app with Flutter as user interface.
Register services in the FlutnetRuntime
![](../../portals/0/Images/Docs/flutnet_project_selection_android_ios_500px-1.jpg)
In order to expose the service to Flutter, you need to register it on the FlutnetRuntime, specifying by the registration key.
The registration must be done before the FlutnetBridge start:
- App → ConfigureFlutnetRuntime() on Android
- ViewController → ViewDidAppear(bool animated) on iOS
using the key "counter_service".
// Init runtime
FlutnetRuntime.Init();
// Register the service
FlutnetRuntime.RegisterPlatformService(new CounterService(), "counter_service");
// Start the bridge .....