Example #1
0
        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);
            });
        }
Example #2
0
        void AddTransitionTimer(TaskCompletionSource <bool> tcs, Fragment fragment, FragmentManager fragmentManager, IReadOnlyCollection <Fragment> fragmentsToRemove, int duration, bool shouldUpdateToolbar)
        {
            Device.StartTimer(TimeSpan.FromMilliseconds(duration), () =>
            {
                tcs.TrySetResult(true);
                Current?.SendAppearing();
                if (shouldUpdateToolbar)
                {
                    UpdateToolbar();
                }

                if (fragmentsToRemove.Count > 0)
                {
                    FragmentTransaction fragmentTransaction = fragmentManager.BeginTransactionEx();

                    foreach (Fragment frag in fragmentsToRemove)
                    {
                        fragmentTransaction.RemoveEx(frag);
                    }

                    fragmentTransaction.CommitAllowingStateLossEx();
                }

                return(false);
            });
        }
Example #3
0
        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);
        }
Example #4
0
        protected override void Dispose(bool disposing)
        {
            if (disposing && !_disposed)
            {
                _disposed = true;

                if (_titleViewRenderer != null)
                {
                    Android.Platform.ClearRenderer(_titleViewRenderer.View);
                    _titleViewRenderer.Dispose();
                    _titleViewRenderer = null;
                }

                _toolbar.RemoveView(_titleView);
                _titleView?.Dispose();
                _titleView = null;

                _toolbar.RemoveView(_titleIconView);
                _titleIconView?.Dispose();
                _titleIconView = null;

                _imageSource = null;

                if (_toolbarTracker != null)
                {
                    _toolbarTracker.CollectionChanged -= ToolbarTrackerOnCollectionChanged;
                    _toolbarTracker.Target             = null;
                    _toolbarTracker = null;
                }

                if (_toolbar != null)
                {
                    _toolbar.SetNavigationOnClickListener(null);
                    _toolbar.Dispose();
                    _toolbar = null;
                }

                if (_drawerLayout != null && _drawerListener != null)
                {
                    _drawerLayout.RemoveDrawerListener(_drawerListener);
                }

                if (_drawerListener != null)
                {
                    _drawerListener.Dispose();
                    _drawerListener = null;
                }

                if (_drawerToggle != null)
                {
                    _drawerToggle.Dispose();
                    _drawerToggle = null;
                }

                if (_backgroundDrawable != null)
                {
                    _backgroundDrawable.Dispose();
                    _backgroundDrawable = null;
                }

                Current = null;

                // We dispose the child renderers after cleaning up everything related to DrawerLayout in case
                // one of the children is a MasterDetailPage (which may dispose of the DrawerLayout).
                if (Element != null)
                {
                    foreach (Element element in PageController.InternalChildren)
                    {
                        var child = element as VisualElement;
                        if (child == null)
                        {
                            continue;
                        }

                        IVisualElementRenderer renderer = Android.Platform.GetRenderer(child);
                        renderer?.Dispose();
                    }

                    var navController = NavigationPageController;

                    navController.PushRequested             -= OnPushed;
                    navController.PopRequested              -= OnPopped;
                    navController.PopToRootRequested        -= OnPoppedToRoot;
                    navController.InsertPageBeforeRequested -= OnInsertPageBeforeRequested;
                    navController.RemovePageRequested       -= OnRemovePageRequested;
                }

                Device.Info.PropertyChanged -= DeviceInfoPropertyChanged;

                // API only exists on newer android YAY
                if ((int)Build.VERSION.SdkInt >= 17)
                {
                    FragmentManager fm = FragmentManager;

                    if (!fm.IsDestroyed)
                    {
                        FragmentTransaction trans = fm.BeginTransactionEx();
                        foreach (Fragment fragment in _fragmentStack)
                        {
                            trans.RemoveEx(fragment);
                        }
                        trans.CommitAllowingStateLossEx();
                        fm.ExecutePendingTransactionsEx();
                    }
                }
            }

            base.Dispose(disposing);
        }