Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using Android.Graphics.Drawables;
using Android.OS;
using Android.Views;
using Android.Views.Animations;
using AndroidX.Activity;
using AndroidX.Fragment.App;
using Microsoft.Maui.LifecycleEvents;
using AAnimation = Android.Views.Animations.Animation;
using AColor = Android.Graphics.Color;
using AView = Android.Views.View;

Expand All @@ -17,6 +19,7 @@ namespace Microsoft.Maui.Controls.Platform
internal partial class ModalNavigationManager
{
ViewGroup? _modalParentView;
AAnimation? _dismissAnimation;
bool _platformActivated;

readonly Stack<string> _modals = [];
Expand All @@ -35,6 +38,8 @@ void OnWindowPropertyChanging(object sender, PropertyChangingEventArgs e)
return;
}

var handler = _currentPage?.Handler;
var windowP = _window.Page;
if (CurrentPage is not null &&
_window.Page != CurrentPage)
{
Expand Down Expand Up @@ -78,45 +83,59 @@ internal void SetModalParentView(ViewGroup viewGroup)
_modalParentView = viewGroup;
}

ViewGroup GetModalParentView()
{
return _modalParentView ??
_window?.PlatformActivity?.Window?.DecorView as ViewGroup ??
throw new InvalidOperationException("Root View Needs to be set");
}

Task<Page> PopModalPlatformAsync(bool animated)
{
Page modal = CurrentPlatformModalPage;
_platformModalPages.Remove(modal);

TaskCompletionSource<Page> tcs = new();

var fragmentManager = WindowMauiContext.GetFragmentManager();

var dialogFragmentId = _modals.Pop();
var dialogFragment = (ModalFragment?)fragmentManager.FindFragmentByTag(dialogFragmentId);

// If for the dialog is null what we want to do?
if (dialogFragment is null)
{
tcs.TrySetResult(modal);
return tcs.Task;
return Task.FromResult(modal);
}

EventHandler? OnDialogDismiss = null;
var source = new TaskCompletionSource<Page>();

OnDialogDismiss = (_, _) =>
if (animated && dialogFragment.View is not null)
{
dialogFragment.DialogDismissEvent -= OnDialogDismiss;
tcs.TrySetResult(modal);
};
_dismissAnimation ??= AnimationUtils.LoadAnimation(WindowMauiContext.Context, Resource.Animation.nav_modal_default_exit_anim)!;

dialogFragment.DialogDismissEvent += OnDialogDismiss;
_dismissAnimation.AnimationEnd += OnAnimationEnded;

if (animated)
{
dialogFragment.Dialog?.Window?.SetWindowAnimations(Resource.Style.modal_exit_animation);
modal.Dispatcher.Dispatch(() => dialogFragment.Dismiss());
dialogFragment.View.StartAnimation(_dismissAnimation);
}
else
{
dialogFragment.Dismiss();
source.TrySetResult(modal);
}

return tcs.Task;
return source.Task;

void OnAnimationEnded(object? sender, AAnimation.AnimationEndEventArgs e)
{
if (sender is not AAnimation animation)
{
return;
}

animation.AnimationEnd -= OnAnimationEnded;
dialogFragment.Dismiss();
source.TrySetResult(modal);
_dismissAnimation = null;
}
}

// The CurrentPage doesn't represent the root of the platform hierarchy.
Expand Down Expand Up @@ -150,6 +169,8 @@ async Task PresentModal(Page modal, bool animated)
{
TaskCompletionSource<bool> animationCompletionSource = new();

var parentView = GetModalParentView();

var dialogFragment = new ModalFragment(WindowMauiContext, modal)
{
Cancelable = false,
Expand All @@ -159,30 +180,36 @@ async Task PresentModal(Page modal, bool animated)
var fragmentManager = WindowMauiContext.GetFragmentManager();
var dialogFragmentId = AView.GenerateViewId().ToString();
_modals.Push(dialogFragmentId);
dialogFragment.Show(fragmentManager, dialogFragmentId);

EventHandler? OnDialogShown = null;

OnDialogShown = (_, _) =>
if (animated)
{
dialogFragment!.DialogShowEvent -= OnDialogShown;
animationCompletionSource.SetResult(true);
};

dialogFragment!.DialogShowEvent += OnDialogShown;
dialogFragment!.AnimationEnded += OnAnimationEnded;

dialogFragment.Show(fragmentManager, dialogFragmentId);
await animationCompletionSource.Task;
}
else
{
animationCompletionSource.TrySetResult(true);
}

await animationCompletionSource.Task;
void OnAnimationEnded(object? sender, EventArgs e)
{
dialogFragment!.AnimationEnded -= OnAnimationEnded;
animationCompletionSource.SetResult(true);
}
}

internal class ModalFragment : DialogFragment
{
Page _modal;
IMauiContext _mauiWindowContext;
NavigationRootManager? _navigationRootManager;
public event EventHandler? DialogShowEvent;
public event EventHandler? DialogDismissEvent;
static readonly ColorDrawable TransparentColorDrawable = new(AColor.Transparent);
bool _pendingAnimation = true;

public event EventHandler? AnimationEnded;


public bool IsAnimated { get; internal set; }

Expand Down Expand Up @@ -210,20 +237,6 @@ public ModalFragment(IMauiContext mauiContext, Page modal)
{
dialog.Window.SetSoftInputMode(attributes.SoftInputMode);
}
EventHandler? OnDialogShown = null;

OnDialogShown = (_, _) =>
{
dialog.ShowEvent -= OnDialogShown;
DialogShowEvent?.Invoke(this, EventArgs.Empty);
};

dialog.ShowEvent += OnDialogShown;

if (IsAnimated)
{
dialog.Window.SetWindowAnimations(Resource.Style.modal_enter_animation);
}

if (mainActivityWindow is not null)
{
Expand Down Expand Up @@ -317,13 +330,29 @@ public override void OnStart()
int width = ViewGroup.LayoutParams.MatchParent;
int height = ViewGroup.LayoutParams.MatchParent;
dialog.Window.SetLayout(width, height);

if (IsAnimated)
{
var animation = AnimationUtils.LoadAnimation(_mauiWindowContext.Context, Resource.Animation.nav_modal_default_enter_anim)!;
View.StartAnimation(animation);

animation.AnimationEnd += OnAnimationEnded;
}

void OnAnimationEnded(object? sender, AAnimation.AnimationEndEventArgs e)
{
if (sender is not AAnimation animation)
{
return;
}

animation.AnimationEnd -= OnAnimationEnded;
FireAnimationEnded();
}
}

public override void OnDismiss(IDialogInterface dialog)
{
base.OnDismiss(dialog);
DialogDismissEvent?.Invoke(this, EventArgs.Empty);
DialogDismissEvent = null;
_modal.PropertyChanged -= OnModalPagePropertyChanged;
_modal.HandlerChanged -= OnPageHandlerChanged;

Expand All @@ -337,8 +366,27 @@ public override void OnDismiss(IDialogInterface dialog)
_mauiWindowContext = null!;
_navigationRootManager?.Disconnect();
_navigationRootManager = null;
base.OnDismiss(dialog);
}

public override void OnDestroy()
{
base.OnDestroy();
FireAnimationEnded();
}

void FireAnimationEnded()
{
if (!_pendingAnimation)
{
return;
}

_pendingAnimation = false;
AnimationEnded?.Invoke(this, EventArgs.Empty);
}


sealed class CustomComponentDialog : ComponentDialog
{
public CustomComponentDialog(Context context, int themeResId) : base(context, themeResId)
Expand Down
7 changes: 0 additions & 7 deletions src/Core/src/Platform/Android/Resources/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,4 @@
<style name="scrollViewTheme">
<item name="scrollViewStyle">@style/scrollViewScrollBars</item>
</style>

<style name="modal_enter_animation" >
<item name="android:windowEnterAnimation">@anim/nav_modal_default_enter_anim</item>
</style>
<style name="modal_exit_animation" >
<item name="android:windowExitAnimation">@anim/nav_modal_default_exit_anim</item>
</style>
</resources>
Loading