void RemovePage(Page page) { if (!_isAttachedToWindow) { PushCurrentPages(); } Fragment fragment = GetPageFragment(page); if (fragment == null) { return; } #if DEBUG // Enables logging of moveToState operations to logcat FragmentManager.EnableDebugLogging(true); #endif // Go ahead and take care of the fragment bookkeeping for the page being removed FragmentTransaction transaction = FragmentManager.BeginTransactionEx(); transaction.RemoveEx(fragment); transaction.CommitAllowingStateLossEx(); // And remove the fragment from our own stack _fragmentStack.Remove(fragment); Device.StartTimer(TimeSpan.FromMilliseconds(10), () => { UpdateToolbar(); return(false); }); }
Task <bool> SwitchContentAsync(Page page, bool animated, bool removed = false, bool popToRoot = false) { if (!Element.IsAttachedToRoot()) { return(Task.FromResult(false)); } var tcs = new TaskCompletionSource <bool>(); Fragment fragment = GetFragment(page, removed, popToRoot); #if DEBUG // Enables logging of moveToState operations to logcat FragmentManager.EnableDebugLogging(true); #endif Current?.SendDisappearing(); Current = page; if (Platform != null) { Platform.NavAnimationInProgress = true; } FragmentTransaction transaction = FragmentManager.BeginTransactionEx(); if (animated) { SetupPageTransition(transaction, !removed); } var fragmentsToRemove = new List <Fragment>(); if (_fragmentStack.Count == 0) { transaction.AddEx(Id, fragment); _fragmentStack.Add(fragment); } else { if (removed) { // pop only one page, or pop everything to the root var popPage = true; while (_fragmentStack.Count > 1 && popPage) { Fragment currentToRemove = _fragmentStack.Last(); _fragmentStack.RemoveAt(_fragmentStack.Count - 1); transaction.HideEx(currentToRemove); fragmentsToRemove.Add(currentToRemove); popPage = popToRoot; } Fragment toShow = _fragmentStack.Last(); // Execute pending transactions so that we can be sure the fragment list is accurate. FragmentManager.ExecutePendingTransactionsEx(); if (FragmentManager.Fragments.Contains(toShow)) { transaction.ShowEx(toShow); } else { transaction.AddEx(Id, toShow); } } else { // push Fragment currentToHide = _fragmentStack.Last(); transaction.HideEx(currentToHide); transaction.AddEx(Id, fragment); _fragmentStack.Add(fragment); } } // We don't currently support fragment restoration, so we don't need to worry about // whether the commit loses state transaction.CommitAllowingStateLossEx(); // The fragment transitions don't really SUPPORT telling you when they end // There are some hacks you can do, but they actually are worse than just doing this: if (animated) { if (!removed) { UpdateToolbar(); if (_drawerToggle != null && NavigationPageController.StackDepth == 2) { AnimateArrowIn(); } } else if (_drawerToggle != null && NavigationPageController.StackDepth == 2) { AnimateArrowOut(); } AddTransitionTimer(tcs, fragment, FragmentManager, fragmentsToRemove, TransitionDuration, removed); } else { AddTransitionTimer(tcs, fragment, FragmentManager, fragmentsToRemove, 1, true); } Context.HideKeyboard(this); if (Platform != null) { Platform.NavAnimationInProgress = false; } return(tcs.Task); }
Task <bool> SwitchContentAsync(Page page, bool animated, bool removed = false, bool popToRoot = false) { var tcs = new TaskCompletionSource <bool>(); Fragment fragment = GetFragment(page, removed, popToRoot); #if DEBUG // Enables logging of moveToState operations to logcat FragmentManager.EnableDebugLogging(true); #endif Current = page; ((Platform)Element.Platform).NavAnimationInProgress = true; FragmentTransaction transaction = FragmentManager.BeginTransaction(); if (animated) { SetupPageTransition(transaction, !removed); } if (_fragmentStack.Count == 0) { transaction.Add(Id, fragment); _fragmentStack.Add(fragment); } else { if (removed) { // pop only one page, or pop everything to the root var popPage = true; while (_fragmentStack.Count > 1 && popPage) { Fragment currentToRemove = _fragmentStack.Last(); _fragmentStack.RemoveAt(_fragmentStack.Count - 1); transaction.Remove(currentToRemove); popPage = popToRoot; } Fragment toShow = _fragmentStack.Last(); // Execute pending transactions so that we can be sure the fragment list is accurate. FragmentManager.ExecutePendingTransactions(); if (FragmentManager.Fragments.Contains(toShow)) { transaction.Show(toShow); } else { transaction.Add(Id, toShow); } } else { // push Fragment currentToHide = _fragmentStack.Last(); transaction.Hide(currentToHide); transaction.Add(Id, fragment); _fragmentStack.Add(fragment); } } // We don't currently support fragment restoration, so we don't need to worry about // whether the commit loses state transaction.CommitAllowingStateLoss(); // The fragment transitions don't really SUPPORT telling you when they end // There are some hacks you can do, but they actually are worse than just doing this: if (animated) { if (!removed) { UpdateToolbar(); if (_drawerToggle != null && ((INavigationPageController)Element).StackDepth == 2) { AnimateArrowIn(); } } else if (_drawerToggle != null && ((INavigationPageController)Element).StackDepth == 2) { AnimateArrowOut(); } Device.StartTimer(TimeSpan.FromMilliseconds(TransitionDuration), () => { tcs.TrySetResult(true); fragment.UserVisibleHint = true; if (removed) { UpdateToolbar(); } return(false); }); } else { Device.StartTimer(TimeSpan.FromMilliseconds(1), () => { tcs.TrySetResult(true); fragment.UserVisibleHint = true; UpdateToolbar(); return(false); }); } Context.HideKeyboard(this); ((Platform)Element.Platform).NavAnimationInProgress = false; // TransitionDuration is how long the built-in animations are, and they are "reversible" in the sense that starting another one slightly before it's done is fine return(tcs.Task); }