Thanks to Xamarin.Essentials and SyncFusion's Circular Gauge control, creating a mobile app that monitors the accelerometer data has never been easier.
Let's take a look at how to implement this control in a Xamarin.Forms app.
- Install the Syncfusion.Xamarin.SfGauge NuGet Package into each project, this includes the Xamarin.iOS, Xamarin.Android, and the .NET Standard Project (if one is being used).
- Install the Xamarin.Essentials NuGet Package into each project, this includes the Xamarin.iOS, Xamarin.Android, and the .NET Standard Project (if one is being used).
To utilize the SyncFusion Circular Gauge, we first need to initialize it in AppDelegate.FinishedLaunching
:
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
...
public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
{
...
Syncfusion.SfGauge.XForms.iOS.SfGaugeRenderer.Init();
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Your SyncFusion License Key");
...
}
}
To utilize the SyncFusion Circular Gauge, we first need to initialize it MainActivity.OnCreate
:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
...
protected override void OnCreate(Bundle savedInstanceState)
{
...
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Your SyncFusion License Key");
...
}
}
- In the Solution Explorer, in the Android project, right-click on References
- In the References menu, select Edit References
- In the Edit References window, select the Packages tab
- In the Packages tab, locate
Mono.Android.Export
- In the Packages tab, ensure
Mono.Android.Export
is checked - In the Edit References window, click OK
This app requires 3 instances of the Circular Gauge Control in our app, so let's start by creating an implementation of SfCircularGauge
using System.Collections.ObjectModel;
using Syncfusion.SfGauge.XForms;
using Xamarin.Forms;
namespace AccelerometerApp
{
class CircularGaugeView : SfCircularGauge
{
public CircularGaugeView(string headerText, double startValue, double endValue)
{
Pointer = new NeedlePointer { AnimationDuration = 0.5 };
var header = new Header
{
Text = headerText,
ForegroundColor = Color.Gray
};
var circularGaugeScale = new Scale
{
Interval = (endValue - startValue) / 10,
StartValue = startValue,
EndValue = endValue,
ShowTicks = true,
ShowLabels = true,
Pointers = { Pointer },
MinorTicksPerInterval = 4,
};
Scales = new ObservableCollection<Scale> { circularGaugeScale };
Headers = new ObservableCollection<Header> { header };
}
public NeedlePointer Pointer { get; }
}
}
In the Xamarin.Forms project, create a new class, AccelerometerPage.cs
:
using System.Linq;
using Xamarin.CommunityToolkit.Markup;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
using static Xamarin.CommunityToolkit.Markup.GridRowsColumns;
namespace AccelerometerApp
{
class AccelerometerPage : ContentPage
{
public AccelerometerPage()
{
InitializeAccelerometer();
Content = new Grid
{
Margin = new Thickness(0, 20),
RowDefinitions = Rows.Define(
(Row.xGauge, Star),
(Row.yGauge, Star),
(Row.zGauge, Star)),
ColumnDefinitions = Columns.Define(Star),
Children =
{
new CircularGaugeView("X-Axis", -1, 1).Row(Row.xGauge),
new CircularGaugeView("Y-Axis", -1, 1).Row(Row.yGauge),
new CircularGaugeView("Z-Axis", -10, 10).Row(Row.zGauge)
}
};
On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
}
enum Row { xGauge, yGauge, zGauge }
void InitializeAccelerometer()
{
try
{
Accelerometer.Start(SensorSpeed.Default);
Accelerometer.ReadingChanged += HandleAccelerometerReadingChanged;
}
catch (FeatureNotSupportedException)
{
System.Diagnostics.Debug.WriteLine("Accelerometer Unavailable");
}
}
void HandleAccelerometerReadingChanged(object sender, AccelerometerChangedEventArgs e)
{
var grid = (Grid)Content;
var xCircularGauge = (CircularGaugeView)grid.Children.First(x => Grid.GetRow(x) is (int)Row.xGauge);
var yCircularGauge = (CircularGaugeView)grid.Children.First(x => Grid.GetRow(x) is (int)Row.yGauge);
var zCircularGauge = (CircularGaugeView)grid.Children.First(x => Grid.GetRow(x) is (int)Row.zGauge);
MainThread.BeginInvokeOnMainThread(() =>
{
xCircularGauge.Pointer.Value = e.Reading.Acceleration.X;
yCircularGauge.Pointer.Value = e.Reading.Acceleration.Y;
zCircularGauge.Pointer.Value = e.Reading.Acceleration.Z;
});
}
}
}
In App.cs
, ensure that MainPage = new AccelerometerPage();
:
using Xamarin.Forms;
namespace AccelerometerApp
{
public class App : Application
{
public App() => MainPage = new AccelerometerPage();
}
}
Brandon Minnick is a Developer Advocate at Microsoft specializing in Xamarin and Azure. As a Developer Advocate, Brandon works closely with the mobile app community, helping them create 5-star apps and provide their feedback to the Microsoft product teams to help improve our tools and empower every person and every organization on the planet to achieve more.