Try to migrate from Xamarin to MAUI
On Xamarin i have simple code for fullscreen loader
Xamarin code
Interface
on root project
namespace SkeletonApp.View.Loader
{
public interface ILodingPageService
{
void InitLoadingPage(Xamarin.Forms.ContentPage loadingIndicatorPage = null);
void ShowLoadingPage();
void HideLoadingPage();
}
}
Implementation
on Android sub-project
using System;
using Android.App;
using Android.Graphics.Drawables;
using Android.Views;
using Plugin.CurrentActivity;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using SkeletonApp.Droid;
using XFPlatform = Xamarin.Forms.Platform.Android.Platform;
using SkeletonApp.View.Loader;
[assembly: Xamarin.Forms.Dependency(typeof(LodingPageServiceDroid))]
namespace SkeletonApp.Droid {
public class LodingPageServiceDroid : ILodingPageService {
private Android.Views.View _nativeView;
private Dialog _dialog;
private bool _isInitialized;
public void InitLoadingPage(ContentPage loadingIndicatorPage) {
// check if the page parameter is available
if (loadingIndicatorPage != null) {
// build the loading page with native base
loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;
loadingIndicatorPage.Layout(new Rectangle(0, 0,
Xamarin.Forms.Application.Current.MainPage.Width,
Xamarin.Forms.Application.Current.MainPage.Height));
var renderer = loadingIndicatorPage.GetOrCreateRenderer();
_nativeView = renderer.View;
_dialog = new Dialog(CrossCurrentActivity.Current.Activity);
_dialog.RequestWindowFeature((int)WindowFeatures.NoTitle);
_dialog.SetCancelable(false);
_dialog.SetContentView(_nativeView);
Window window = _dialog.Window;
window.SetLayout(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
window.ClearFlags(WindowManagerFlags.DimBehind);
window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));
_isInitialized = true;
}
}
public void ShowLoadingPage() {
// check if the user has set the page or not
if (_isInitialized == false) {
InitLoadingPage(new DefaultLoader()); // set the default page
}
_dialog.Show();
}
private void XamFormsPage_Appearing(object sender, EventArgs e)
{
var animation = new Animation(callback: d => ((ContentPage)sender).Content.Rotation = d,
start: ((ContentPage)sender).Content.Rotation,
end: ((ContentPage)sender).Content.Rotation + 360,
easing: Easing.Linear);
animation.Commit(((ContentPage)sender).Content, "RotationLoopAnimation", 16, 800, null, null, () => true);
}
public void HideLoadingPage() {
_dialog.Hide();
}
}
internal static class PlatformExtension {
public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable) {
var renderer = XFPlatform.GetRenderer(bindable);
if (renderer == null)
{
renderer = XFPlatform.CreateRendererWithContext(bindable, CrossCurrentActivity.Current.Activity);
XFPlatform.SetRenderer(bindable, renderer);
}
return renderer;
}
}
}
Call loader on root project
// Show loader
DependencyService.Get<ILodingPageService>().ShowLoadingPage();
// Hide loader
DependencyService.Get<ILodingPageService>().HideLoadingPage();
And this works fine
Try to migrate on MAUI
Interface
– same
Implementation
change to
using Android.App;
using Android.Graphics.Drawables;
using AndroidViews = Android.Views;
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
using SkeletonAppMAUI.Tools.View.Loader;
using AndroidPlatform = Microsoft.Maui.Controls.Compatibility.Platform.Android.Platform;
using AndroidColor = Android.Graphics.Color;
[assembly: Microsoft.Maui.Controls.Dependency(typeof(SkeletonAppMAUI.Platforms.Android.LodingPageServiceDroid))]
namespace SkeletonAppMAUI.Platforms.Android {
public class LodingPageServiceDroid : ILodingPageService {
private AndroidViews.View _nativeView;
private Dialog _dialog;
private bool _isInitialized;
public void InitLoadingPage(ContentPage loadingIndicatorPage) {
// check if the page parameter is available
if (loadingIndicatorPage != null) {
// build the loading page with native base
loadingIndicatorPage.Parent = Microsoft.Maui.Controls.Application.Current.MainPage;
loadingIndicatorPage.Layout(new Rect(0, 0,
Microsoft.Maui.Controls.Application.Current.MainPage.Width,
Microsoft.Maui.Controls.Application.Current.MainPage.Height));
var renderer = loadingIndicatorPage.GetOrCreateRenderer();
_nativeView = renderer.View;
_dialog = new Dialog(Microsoft.Maui.ApplicationModel.Platform.CurrentActivity);
_dialog.RequestWindowFeature((int)AndroidViews.WindowFeatures.NoTitle);
_dialog.SetCancelable(false);
_dialog.SetContentView(_nativeView);
AndroidViews.Window window = _dialog.Window;
window.SetLayout(AndroidViews.ViewGroup.LayoutParams.MatchParent, AndroidViews.ViewGroup.LayoutParams.MatchParent);
window.ClearFlags(AndroidViews.WindowManagerFlags.DimBehind);
window.SetBackgroundDrawable(new ColorDrawable(AndroidColor.Transparent));
_isInitialized = true;
}
}
public void ShowLoadingPage() {
// check if the user has set the page or not
if (_isInitialized == false) {
InitLoadingPage(new DefaultLoader()); // set the default page
}
// showing the native loading page
_dialog.Show();
}
private void XamFormsPage_Appearing(object sender, EventArgs e) {
var animation = new Animation(callback: d => ((ContentPage)sender).Content.Rotation = d,
start: ((ContentPage)sender).Content.Rotation,
end: ((ContentPage)sender).Content.Rotation + 360,
easing: Easing.Linear);
animation.Commit(((ContentPage)sender).Content, "RotationLoopAnimation", 16, 800, null, null, () => true);
}
public void HideLoadingPage() {
// Hide the page
_dialog.Hide();
}
}
internal static class PlatformExtension {
public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable) {
var renderer = AndroidPlatform.GetRenderer(bindable);
if (renderer == null)
{
renderer = AndroidPlatform.CreateRendererWithContext(bindable, Microsoft.Maui.ApplicationModel.Platform.CurrentActivity);
AndroidPlatform.SetRenderer(bindable, renderer);
}
return renderer;
}
}
}
And when i try to show loader (DependencyService.Get<ILodingPageService>().ShowLoadingPage();
) i got fatal about context is empty
Forms.MauiContext.Handlers cannot be null here
For Xamarin I saved the context using the Nuget package Plugin.CurrentActivity
in Android Application class, in MAUI it works out of the box using Microsoft.Maui.ApplicationModel.Platform.CurrentActivity
(as I understand).
Or did I misunderstand the MAUI concept about getting the context in the target platform?
Xamarin code based by this github repo