diff --git a/src/Toolkit/Toolkit.Maui/AppHostBuilderExtensions.cs b/src/Toolkit/Toolkit.Maui/AppHostBuilderExtensions.cs index f2ec37c23..47cd6c2db 100644 --- a/src/Toolkit/Toolkit.Maui/AppHostBuilderExtensions.cs +++ b/src/Toolkit/Toolkit.Maui/AppHostBuilderExtensions.cs @@ -15,7 +15,7 @@ public static class AppHostBuilderExtensions /// The host builder public static MauiAppBuilder UseArcGISToolkit(this MauiAppBuilder builder) { -#if WINDOWS || __IOS__ +#if WINDOWS || __IOS__ || ANDROID builder.ConfigureMauiHandlers(handler => handler.AddHandler()); #endif builder.ConfigureFonts(fonts => fonts diff --git a/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.Android.cs b/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.Android.cs new file mode 100644 index 000000000..8486f4cf3 --- /dev/null +++ b/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.Android.cs @@ -0,0 +1,108 @@ +#if ANDROID +using Android.Media; +using Android.Widget; +using AndroidX.CoordinatorLayout.Widget; +using Microsoft.Maui.ApplicationModel; +using Microsoft.Maui.Handlers; + +namespace Esri.ArcGISRuntime.Toolkit.Maui.Internal; + +internal partial class MauiMediaElementHandler : ViewHandler +{ + protected override MauiVideoPlayer CreatePlatformView() => new(Context, VirtualView); + + protected override void ConnectHandler(MauiVideoPlayer platformView) + { + base.ConnectHandler(platformView); + platformView.UpdateSource(VirtualView.Source); + } + + protected override void DisconnectHandler(MauiVideoPlayer platformView) + { + platformView.Dispose(); + base.DisconnectHandler(platformView); + } + + public void UpdateSource(Uri? source) + { + PlatformView?.UpdateSource(source); + } +} + +internal sealed class MauiVideoPlayer : CoordinatorLayout +{ + private readonly RelativeLayout _relativeLayout; + private readonly VideoView _videoView; + private readonly MediaController _mediaController; + + public MauiVideoPlayer(Android.Content.Context context, MauiMediaElement mediaElement) : base(context) + { + SetBackgroundColor(Android.Graphics.Color.Black); + + _relativeLayout = new RelativeLayout(context) + { + LayoutParameters = new CoordinatorLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent) + { + Gravity = (int)Android.Views.GravityFlags.Center, + }, + }; + + _videoView = new VideoView(context) + { + LayoutParameters = new RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent), + }; + + _relativeLayout.AddView(_videoView); + AddView(_relativeLayout); + + _mediaController = new MediaController(context); + _mediaController.SetAnchorView(_videoView); + _mediaController.SetMediaPlayer(_videoView); + _videoView.SetMediaController(_mediaController); + } + + protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) + { + var density = Context?.Resources?.DisplayMetrics?.Density ?? 1f; + var heightInPixels = (int)(180 * density); + var exactHeight = Android.Views.View.MeasureSpec.MakeMeasureSpec(heightInPixels, Android.Views.MeasureSpecMode.Exactly); + + _relativeLayout.Measure(widthMeasureSpec, exactHeight); + SetMeasuredDimension(Android.Views.View.MeasureSpec.GetSize(widthMeasureSpec), Android.Views.View.MeasureSpec.GetSize(exactHeight)); + } + + protected override void OnLayout(bool changed, int l, int t, int r, int b) + { + _relativeLayout.Layout(0, 0, r - l, b - t); + } + + public void UpdateSource(Uri? source) + { + if (source is null) + { + _videoView.StopPlayback(); + return; + } + + _videoView.SetVideoURI(Android.Net.Uri.Parse(source.ToString())); + _videoView.RequestFocus(); + _videoView.Start(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _videoView.SetMediaController(null); + _videoView.StopPlayback(); + _mediaController.SetMediaPlayer(null); + _mediaController.Dispose(); + _videoView.Dispose(); + _relativeLayout.Dispose(); + } + + base.Dispose(disposing); + } +} + +#endif \ No newline at end of file diff --git a/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.cs b/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.cs index 679b6a3ce..b749a4553 100644 --- a/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.cs +++ b/src/Toolkit/Toolkit.Maui/Internal/MauiMediaElementHandler.cs @@ -1,4 +1,4 @@ -#if WINDOWS || __IOS__ +#if WINDOWS || __IOS__ || ANDROID using Microsoft.Maui.Handlers; namespace Esri.ArcGISRuntime.Toolkit.Maui.Internal