Flutnet Events Example

→ Exposing your C# Events to Flutter

 

The latest version of all the official Flutnet samples can be found in the official GitHub repository: https://github.com/flutnet/samples/

 

Overview

 

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:

  1. public int GetValue ( ) → Flutter request the current counter value;
  2. public void Increment ( ) → Flutter request to increment the counter;
  3. public void Decrement ( ) → Flutter request to decrement the counter. 

one PlatformEvent:

  1.  public event EventHandler< CounterChangedArgs > ValueChanged

with one PlatformData:

  1. 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...)

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 

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

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

// 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

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

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 .....