protected override void AddChildView(VisualElement childView)
        {
            _pageContainer = null;

            Page page = childView as NavigationPage ?? (Page)(childView as TabbedPage);

            if (page == null)
            {
                // Not a NavigationPage or TabbedPage? Just do the normal thing
                base.AddChildView(childView);
            }
            else
            {
                // The renderers for NavigationPage and TabbedPage both host fragments, so they need to be wrapped in a
                // FragmentContainer in order to get isolated fragment management

                Fragment fragment = FragmentContainer.CreateInstance(page);

                var fc = fragment as FragmentContainer;
                fc?.SetOnCreateCallback(pc =>
                {
                    _pageContainer = pc;
                    SetDefaultBackgroundColor(pc.Child);
                });

                FragmentTransaction transaction = FragmentManager.BeginTransaction();
                transaction.DisallowAddToBackStack();
                transaction.Add(Id, fragment);
                transaction.SetTransition((int)FragmentTransit.FragmentOpen);
                transaction.Commit();
            }
        }
Exemplo n.º 2
0
        public override Fragment GetItem(int position)
        {
            var fragment = FragmentContainer.CreateInstance(_page.Children[position]);

            _fragments.Add(fragment);

            return(fragment);
        }
        protected override void AddChildView(VisualElement childView)
        {
            _pageContainer = null;

            Page page = childView as NavigationPage ?? (Page)(childView as TabbedPage);

            if (page == null)
            {
                // The thing we're adding is not a NavigationPage or TabbedPage, so we can just use the old AddChildView

                if (_currentFragment != null)
                {
                    // But first, if the previous occupant of this container was a fragment, we need to remove it properly
                    FragmentTransaction transaction = FragmentManager.BeginTransaction();
                    transaction.DisallowAddToBackStack();
                    transaction.Remove(_currentFragment);
                    transaction.SetTransition((int)FragmentTransit.None);
                    transaction.Commit();

                    _currentFragment = null;
                }

                base.AddChildView(childView);
            }
            else
            {
                // The renderers for NavigationPage and TabbedPage both host fragments, so they need to be wrapped in a
                // FragmentContainer in order to get isolated fragment management
                Fragment fragment = FragmentContainer.CreateInstance(page);

                var fc = fragment as FragmentContainer;

                fc?.SetOnCreateCallback(pc =>
                {
                    _pageContainer = pc;
                    SetDefaultBackgroundColor(pc.Child);
                });

                FragmentTransaction transaction = FragmentManager.BeginTransaction();
                transaction.DisallowAddToBackStack();

                if (_currentFragment != null)
                {
                    transaction.Remove(_currentFragment);
                }

                transaction.Add(Id, fragment);
                transaction.SetTransition((int)FragmentTransit.None);
                transaction.Commit();

                _currentFragment = fragment;

                new Handler(Looper.MainLooper).PostAtFrontOfQueue(() => FragmentManager.ExecutePendingTransactions());
            }
        }
Exemplo n.º 4
0
        void InsertPageBefore(Page page, Page before)
        {
            UpdateToolbar();

            int index = Element.InternalChildren.IndexOf(before);

            if (index == -1)
            {
                throw new InvalidOperationException("This should never happen, please file a bug");
            }

            Fragment fragment = FragmentContainer.CreateInstance(page);

            _fragmentStack.Insert(index, fragment);
        }
Exemplo n.º 5
0
        Fragment GetFragment(Page page, bool removed, bool popToRoot)
        {
            // pop
            if (removed)
            {
                return(_fragmentStack[_fragmentStack.Count - 2]);
            }

            // pop to root
            if (popToRoot)
            {
                return(_fragmentStack[0]);
            }

            // push
            return(FragmentContainer.CreateInstance(page));
        }
Exemplo n.º 6
0
        void InsertPageBefore(Page page, Page before)
        {
            if (!_isAttachedToWindow)
            {
                PushCurrentPages();
            }

            UpdateToolbar();

            int index = PageController.InternalChildren.IndexOf(before);

            if (index == -1)
            {
                throw new InvalidOperationException("This should never happen, please file a bug");
            }

            Fragment fragment = FragmentContainer.CreateInstance(page);

            _fragmentStack.Insert(index, fragment);
        }
Exemplo n.º 7
0
        Task <bool> SwitchContentAsync(Page view, bool animated, bool removed = false, bool popToRoot = false)
        {
            var             activity  = (FormsAppCompatActivity)Context;
            var             tcs       = new TaskCompletionSource <bool>();
            Fragment        fragment  = FragmentContainer.CreateInstance(view);
            FragmentManager fm        = FragmentManager;
            List <Fragment> fragments = _fragmentStack;

            Current = view;

            FragmentTransaction transaction = fm.BeginTransaction();

            if (animated)
            {
                SetupPageTransition(transaction, !removed);
            }

            transaction.DisallowAddToBackStack();

            if (fragments.Count == 0)
            {
                transaction.Add(Id, fragment);
                fragments.Add(fragment);
            }
            else
            {
                if (removed)
                {
                    // pop only one page, or pop everything to the root
                    var popPage = true;
                    while (fragments.Count > 1 && popPage)
                    {
                        Fragment currentToRemove = fragments.Last();
                        fragments.RemoveAt(fragments.Count - 1);
                        transaction.Remove(currentToRemove);
                        popPage = popToRoot;
                    }

                    Fragment toShow = fragments.Last();
                    // Execute pending transactions so that we can be sure the fragment list is accurate.
                    fm.ExecutePendingTransactions();
                    if (fm.Fragments.Contains(toShow))
                    {
                        transaction.Show(toShow);
                    }
                    else
                    {
                        transaction.Add(Id, toShow);
                    }
                }
                else
                {
                    // push
                    Fragment currentToHide = fragments.Last();
                    transaction.Hide(currentToHide);
                    transaction.Add(Id, fragment);
                    fragments.Add(fragment);
                }
            }
            transaction.Commit();

            // 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 && Element.StackDepth == 2)
                    {
                        AnimateArrowIn();
                    }
                }
                else if (_drawerToggle != null && Element.StackDepth == 2)
                {
                    AnimateArrowOut();
                }

                Device.StartTimer(TimeSpan.FromMilliseconds(200), () =>
                {
                    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);

            // 200ms is how long the animations are, and they are "reversible" in the sense that starting another one slightly before it's done is fine

            return(tcs.Task);
        }
Exemplo n.º 8
0
        protected override void AddChildView(VisualElement childView)
        {
            _pageContainer = null;

            Page page = childView as NavigationPage ?? (Page)(childView as TabbedPage);

            if (page == null)
            {
                // The thing we're adding is not a NavigationPage or TabbedPage, so we can just use the old AddChildView

                if (_currentFragment != null)
                {
                    // But first, if the previous occupant of this container was a fragment, we need to remove it properly
                    FragmentTransaction transaction = FragmentManager.BeginTransaction();
                    transaction.Remove(_currentFragment);
                    transaction.SetTransition((int)FragmentTransit.None);

                    // This is a removal of a fragment that's not going on the back stack; there's no reason to care
                    // whether its state gets successfully saved, since we'll never restore it. Ergo, CommitAllowingStateLoss
                    transaction.CommitAllowingStateLoss();

                    _currentFragment = null;
                }

                base.AddChildView(childView);
            }
            else
            {
                // The renderers for NavigationPage and TabbedPage both host fragments, so they need to be wrapped in a
                // FragmentContainer in order to get isolated fragment management
                Fragment fragment = FragmentContainer.CreateInstance(page);

                var fc = fragment as FragmentContainer;

                fc?.SetOnCreateCallback(pc =>
                {
                    _pageContainer = pc;
                    SetDefaultBackgroundColor(pc.Child);
                });

                FragmentTransaction transaction = FragmentManager.BeginTransaction();

                if (_currentFragment != null)
                {
                    transaction.Remove(_currentFragment);
                }

                transaction.Add(Id, fragment);
                transaction.SetTransition((int)FragmentTransit.None);

                // We don't currently support fragment restoration
                // So we don't need to worry about loss of this fragment's state
                transaction.CommitAllowingStateLoss();

                _currentFragment = fragment;

                new Handler(Looper.MainLooper).PostAtFrontOfQueue(() =>
                {
                    if (_pageContainer == null)
                    {
                        // The view we're hosting in the fragment was never created (possibly we're already
                        // navigating to another page?) so there's nothing to commit
                        return;
                    }

                    FragmentManager.ExecutePendingTransactions();
                });
            }
        }
        protected override void AddChildView(VisualElement childView)
        {
            _pageContainer = null;

            Page page = childView as NavigationPage ?? (Page)(childView as TabbedPage);

            if (page == null)
            {
                // The thing we're adding is not a NavigationPage or TabbedPage, so we can just use the old AddChildView

                if (_currentFragment != null)
                {
                    if (!_parent.IsAttachedToRoot())
                    {
                        return;
                    }

                    // But first, if the previous occupant of this container was a fragment, we need to remove it properly
                    FragmentTransaction transaction = FragmentManager.BeginTransactionEx();
                    transaction.RemoveEx(_currentFragment);
                    transaction.SetTransitionEx((int)FragmentTransit.None);

                    if (IsAttachedToWindow)
                    {
                        ExecuteTransaction(transaction);
                    }
                    else
                    {
                        _transaction = transaction;
                    }

                    _currentFragment = null;
                }

                base.AddChildView(childView);
            }
            else
            {
                if (!_parent.IsAttachedToRoot())
                {
                    return;
                }

                // The renderers for NavigationPage and TabbedPage both host fragments, so they need to be wrapped in a
                // FragmentContainer in order to get isolated fragment management
                Fragment fragment = FragmentContainer.CreateInstance(page);

                var fc = fragment as FragmentContainer;

                fc?.SetOnCreateCallback(pc =>
                {
                    _pageContainer = pc;
                    UpdateFlowDirection();
                    SetDefaultBackgroundColor(pc.Child);
                });

                FragmentTransaction transaction = FragmentManager.BeginTransactionEx();

                if (_currentFragment != null)
                {
                    transaction.RemoveEx(_currentFragment);
                }

                transaction.AddEx(Id, fragment);
                transaction.SetTransitionEx((int)FragmentTransit.None);

                if (IsAttachedToWindow)
                {
                    ExecuteTransaction(transaction);
                }
                else
                {
                    _transaction = transaction;
                }

                _currentFragment = fragment;
            }
        }
Exemplo n.º 10
0
 public override Fragment GetItem(int position)
 {
     return(FragmentContainer.CreateInstance(_page.Children[position]));
 }
        Task <bool> SwitchContentAsync(Page view, bool animated, bool removed = false, bool popToRoot = false)
        {
            var             tcs      = new TaskCompletionSource <bool>();
            Fragment        fragment = FragmentContainer.CreateInstance(view);
            FragmentManager fm       = FragmentManager;

#if DEBUG
            // Enables logging of moveToState operations to logcat
            FragmentManager.EnableDebugLogging(true);
#endif

            List <Fragment> fragments = _fragmentStack;

            Current = view;

            ((Platform)Element.Platform).NavAnimationInProgress = true;
            FragmentTransaction transaction = fm.BeginTransaction();

            if (animated)
            {
                SetupPageTransition(transaction, !removed);
            }

            transaction.DisallowAddToBackStack();

            if (fragments.Count == 0)
            {
                transaction.Add(Id, fragment);
                fragments.Add(fragment);
            }
            else
            {
                if (removed)
                {
                    // pop only one page, or pop everything to the root
                    var popPage = true;
                    while (fragments.Count > 1 && popPage)
                    {
                        Fragment currentToRemove = fragments.Last();
                        fragments.RemoveAt(fragments.Count - 1);
                        transaction.Remove(currentToRemove);
                        popPage = popToRoot;
                    }

                    Fragment toShow = fragments.Last();
                    // Execute pending transactions so that we can be sure the fragment list is accurate.
                    fm.ExecutePendingTransactions();
                    if (fm.Fragments.Contains(toShow))
                    {
                        transaction.Show(toShow);
                    }
                    else
                    {
                        transaction.Add(Id, toShow);
                    }
                }
                else
                {
                    // push
                    Fragment currentToHide = fragments.Last();
                    transaction.Hide(currentToHide);
                    transaction.Add(Id, fragment);
                    fragments.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);
        }
Exemplo n.º 12
0
        protected override void AddChildView(VisualElement childView)
        {
            _pageContainer = null;

            Page page = childView as NavigationPage ?? (Page)(childView as TabbedPage);

            if (page == null)
            {
                // The thing we're adding is not a NavigationPage or TabbedPage, so we can just use the old AddChildView

                if (_currentFragment != null)
                {
                    if (!_parent.IsAttachedToRoot())
                    {
                        return;
                    }

                    // But first, if the previous occupant of this container was a fragment, we need to remove it properly
                    FragmentTransaction transaction = FragmentManager.BeginTransactionEx();
                    transaction.RemoveEx(_currentFragment);
                    transaction.SetTransitionEx((int)FragmentTransit.None);

                    // This is a removal of a fragment that's not going on the back stack; there's no reason to care
                    // whether its state gets successfully saved, since we'll never restore it. Ergo, CommitAllowingStateLoss
                    transaction.CommitAllowingStateLossEx();

                    _currentFragment = null;
                }

                base.AddChildView(childView);
            }
            else
            {
                if (!_parent.IsAttachedToRoot())
                {
                    return;
                }

                // The renderers for NavigationPage and TabbedPage both host fragments, so they need to be wrapped in a
                // FragmentContainer in order to get isolated fragment management
                Fragment fragment = FragmentContainer.CreateInstance(page);

                var fc = fragment as FragmentContainer;

                fc?.SetOnCreateCallback(pc =>
                {
                    _pageContainer = pc;
                    UpdateFlowDirection();
                    SetDefaultBackgroundColor(pc.Child);
                });

                FragmentTransaction transaction = FragmentManager.BeginTransactionEx();

                if (_currentFragment != null)
                {
                    transaction.RemoveEx(_currentFragment);
                }

                transaction.AddEx(Id, fragment);
                transaction.SetTransitionEx((int)FragmentTransit.None);

                // We don't currently support fragment restoration
                // So we don't need to worry about loss of this fragment's state
                transaction.CommitAllowingStateLossEx();

                _currentFragment = fragment;
            }
        }