protected virtual void OnFragmentPopped(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute)
 {
 }
        protected virtual void PerformShowFragmentTransaction(
            FragmentManager fragmentManager,
            MvxFragmentPresentationAttribute attribute,
            MvxViewModelRequest request)
        {
            var fragmentName = FragmentJavaName(attribute.ViewType);
            var fragment     = CreateFragment(attribute, fragmentName);

            // MvxNavigationService provides an already instantiated ViewModel here,
            // therefore just assign it
            if (request is MvxViewModelInstanceRequest instanceRequest)
            {
                fragment.ViewModel = instanceRequest.ViewModelInstance;
            }
            else
            {
                var bundle            = new Bundle();
                var serializedRequest = NavigationSerializer.Serializer.SerializeObject(request);
                bundle.PutString(ViewModelRequestBundleKey, serializedRequest);

                var fragmentView = fragment.ToFragment();
                if (fragmentView != null)
                {
                    fragmentView.Arguments = bundle;
                }
            }

            var ft = fragmentManager.BeginTransaction();

            if (attribute.SharedElements != null)
            {
                foreach (var item in attribute.SharedElements)
                {
                    string name = item.Key;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = ViewCompat.GetTransitionName(item.Value);
                    }
                    ft.AddSharedElement(item.Value, name);
                }
            }
            if (!attribute.EnterAnimation.Equals(int.MinValue) && !attribute.ExitAnimation.Equals(int.MinValue))
            {
                if (!attribute.PopEnterAnimation.Equals(int.MinValue) && !attribute.PopExitAnimation.Equals(int.MinValue))
                {
                    ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation, attribute.PopEnterAnimation, attribute.PopExitAnimation);
                }
                else
                {
                    ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation);
                }
            }
            if (attribute.TransitionStyle != int.MinValue)
            {
                ft.SetTransitionStyle(attribute.TransitionStyle);
            }

            if (attribute.AddToBackStack == true)
            {
                ft.AddToBackStack(fragmentName);
            }

            ft.Replace(attribute.FragmentContentId, (Fragment)fragment, fragmentName);
            ft.CommitAllowingStateLoss();
        }
        protected virtual void OnBeforeFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
        {
            if (CurrentActivity is IMvxAndroidSharedElements sharedElementsActivity)
            {
                var elements = new List <string>();

                foreach (KeyValuePair <string, View> item in sharedElementsActivity.FetchSharedElementsToAnimate(attribute, request))
                {
                    var transitionName = item.Value.GetTransitionNameSupport();
                    if (!string.IsNullOrEmpty(transitionName))
                    {
                        ft.AddSharedElement(item.Value, transitionName);
                        elements.Add($"{item.Key}:{transitionName}");
                    }
                    else
                    {
                        MvxLog.Instance.Warn("A XML transitionName is required in order to transition a control when navigating.");
                    }
                }

                if (elements.Count > 0)
                {
                    fragment.Arguments.PutString(SharedElementsBundleKey, string.Join("|", elements));
                }
            }

            if (!attribute.EnterAnimation.Equals(int.MinValue) && !attribute.ExitAnimation.Equals(int.MinValue))
            {
                if (!attribute.PopEnterAnimation.Equals(int.MinValue) && !attribute.PopExitAnimation.Equals(int.MinValue))
                {
                    ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation, attribute.PopEnterAnimation, attribute.PopExitAnimation);
                }
                else
                {
                    ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation);
                }
            }

            if (attribute.TransitionStyle != int.MinValue)
            {
                ft.SetTransitionStyle(attribute.TransitionStyle);
            }
        }
 protected virtual void OnFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
 {
 }
Beispiel #5
0
        protected virtual void PerformShowFragmentTransaction(
            FragmentManager fragmentManager,
            MvxFragmentPresentationAttribute attribute,
            MvxViewModelRequest request)
        {
            ValidateArguments(attribute, request);

            if (fragmentManager == null)
            {
                throw new ArgumentNullException(nameof(fragmentManager));
            }

            var fragmentName = attribute.Tag ?? attribute.ViewType.FragmentJavaName();

            IMvxFragmentView?fragmentView = null;

            if (attribute.IsCacheableFragment)
            {
                fragmentView = (IMvxFragmentView)fragmentManager.FindFragmentByTag(fragmentName);
            }

            if (fragmentView == null && attribute.ViewType != null)
            {
                fragmentView = CreateFragment(fragmentManager, attribute, attribute.ViewType);
            }

            var fragment = fragmentView.ToFragment();

            if (fragment == null)
            {
                throw new MvxException($"Fragment {fragmentName} is null. Cannot perform Fragment Transaction.");
            }

            // MvxNavigationService provides an already instantiated ViewModel here
            if (request is MvxViewModelInstanceRequest instanceRequest)
            {
                fragmentView !.ViewModel = instanceRequest.ViewModelInstance;
            }

            // save MvxViewModelRequest in the Fragment's Arguments
#pragma warning disable CA2000 // Dispose objects before losing scope
            var bundle = new Bundle();
#pragma warning restore CA2000 // Dispose objects before losing scope
            var serializedRequest = NavigationSerializer.Serializer.SerializeObject(request);
            bundle.PutString(ViewModelRequestBundleKey, serializedRequest);

            if (fragment.Arguments == null)
            {
                fragment.Arguments = bundle;
            }
            else
            {
                fragment.Arguments.Clear();
                fragment.Arguments.PutAll(bundle);
            }

            var ft = fragmentManager.BeginTransaction();

            OnBeforeFragmentChanging(ft, fragment, attribute, request);

            if (attribute.AddToBackStack)
            {
                ft.AddToBackStack(fragmentName);
            }

            OnFragmentChanging(ft, fragment, attribute, request);

            if (attribute.AddFragment && fragment.IsAdded)
            {
                ft.Show(fragment);
            }
            else if (attribute.AddFragment)
            {
                ft.Add(attribute.FragmentContentId, fragment, fragmentName);
            }
            else
            {
                ft.Replace(attribute.FragmentContentId, fragment, fragmentName);
            }

            ft.CommitAllowingStateLoss();

            OnFragmentChanged(ft, fragment, attribute, request);
        }
 protected virtual void OnBeforeFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute)
 {
     if (attribute.SharedElements != null)
     {
         foreach (var item in attribute.SharedElements)
         {
             string name = item.Key;
             if (string.IsNullOrEmpty(name))
             {
                 name = ViewCompat.GetTransitionName(item.Value);
             }
             ft.AddSharedElement(item.Value, name);
         }
     }
     if (!attribute.EnterAnimation.Equals(int.MinValue) && !attribute.ExitAnimation.Equals(int.MinValue))
     {
         if (!attribute.PopEnterAnimation.Equals(int.MinValue) && !attribute.PopExitAnimation.Equals(int.MinValue))
         {
             ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation, attribute.PopEnterAnimation, attribute.PopExitAnimation);
         }
         else
         {
             ft.SetCustomAnimations(attribute.EnterAnimation, attribute.ExitAnimation);
         }
     }
     if (attribute.TransitionStyle != int.MinValue)
     {
         ft.SetTransitionStyle(attribute.TransitionStyle);
     }
 }
 protected override void ShowFragment(Type view, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
 {
     base.ShowFragment(view, attribute, request);
 }
 protected override bool CloseFragment(IMvxViewModel viewModel, MvxFragmentPresentationAttribute attribute)
 {
     return(base.CloseFragment(viewModel, attribute));
 }
        protected override bool TryPerformCloseFragmentTransaction(FragmentManager fragmentManager, MvxFragmentPresentationAttribute fragmentAttribute)
        {
            var fragmentName = FragmentJavaName(fragmentAttribute.ViewType);

            var fragmentTransaction = fragmentManager.BeginTransaction();

            fragmentTransaction.DisallowAddToBackStack();

            PopFragment(fragmentManager, fragmentTransaction, fragmentAttribute, fragmentName, true);

            var newLastCachedFragment = FragmentsBackStack?.LastOrDefault();

            if (newLastCachedFragment != null)
            {
                PushFragment(fragmentManager, fragmentTransaction, null, null, newLastCachedFragment.ViewModel, newLastCachedFragment.Key);
            }

            fragmentTransaction.CommitNow();

            return(true);
        }
 protected virtual void AddFragmentAttributeToCache(MvxFragmentPresentationAttribute attribute)
 {
     PresentationAttributesCache.Add(attribute);
 }
        protected override void PerformShowFragmentTransaction(FragmentManager fragmentManager, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
        {
            var navigationType = NavigationType.None;

            if (request.ParameterValues != null && request.ParameterValues.TryGetValue("NavigationType", out string typeStr) && Enum.TryParse(typeStr, out navigationType))
            {
                SetupAttribute(attribute, navigationType);
            }
            else if (request is MvxViewModelInstanceRequest instanceRequest)
            {
                navigationType = (instanceRequest.ViewModelInstance as IBaseViewModel)?.VmNavigationType ?? NavigationType.None;
                SetupAttribute(attribute, navigationType);
            }

            if (navigationType == NavigationType.PresentModal)
            {
                lock (this)
                {
                    _presentedModalFragments++;
                }
            }

            var fragmentName = FragmentJavaName(attribute.ViewType);

            IMvxViewModel viewModel = null;

            // MvxNavigationService provides an already instantiated ViewModel here
            if (request is MvxViewModelInstanceRequest)
            {
                viewModel = (request as MvxViewModelInstanceRequest).ViewModelInstance;
            }

            OnBeforeNavigation(fragmentManager, attribute, request);

            var fragmentTransaction = fragmentManager.BeginTransaction();

            fragmentTransaction.DisallowAddToBackStack();

            var oldCachedFragments = new List <ViewModelBundleCache>(FragmentsBackStack);

            var isSameFragmentInBackStack = oldCachedFragments.Any(x => x.Key == fragmentName);

            //check if user has requested transition to single ViewModel added in cache earlier
            var isNavigationIgnored = (navigationType == NavigationType.ClearAndPush && oldCachedFragments.Count == 1 && isSameFragmentInBackStack);

            if (!isNavigationIgnored)
            {
                var firstOldFragment = oldCachedFragments.FirstOrDefault();
                var isMovingToRoot   = navigationType == NavigationType.ClearAndPush && firstOldFragment?.Key == fragmentName;

                if (isMovingToRoot)
                {
                    oldCachedFragments.Remove(firstOldFragment);
                }

                //remove or detach current fragment(s) if navigationType not equal PresentModal and there are no modal fragments in BackStack
                if (navigationType != NavigationType.PresentModal && !WasPresentedModalFragment)
                {
                    foreach (var oldCachedFragment in oldCachedFragments)
                    {
                        var oldFragmentsRemoved = isMovingToRoot || navigationType == NavigationType.ClearAndPush || navigationType == NavigationType.DoubleClearAndPush;
                        PopFragment(fragmentManager, fragmentTransaction, null, oldCachedFragment.Key, oldFragmentsRemoved, true);
                    }
                }

                if (isMovingToRoot)
                {
                    PushFragment(fragmentManager, fragmentTransaction, null, null, firstOldFragment.ViewModel, firstOldFragment.Key);
                }
                else
                {
                    //add or attach new fragment
                    var tag = fragmentName;
                    if (navigationType == NavigationType.DoublePush && isSameFragmentInBackStack)
                    {
                        tag = GetFragmentTag(fragmentName, viewModel);
                    }

                    if (attribute.AddToBackStack == true)
                    {
                        AddFragmentToBackStack(CreateCacheBundle(tag, viewModel));
                    }

                    PushFragment(fragmentManager, fragmentTransaction, attribute, request, viewModel, fragmentName, tag);
                }

                if (!fragmentTransaction.IsEmpty)
                {
                    fragmentTransaction.CommitNow();
                }

                OnFragmentChanged(fragmentTransaction, null, attribute);
            }
        }
        protected virtual void PopFragment(FragmentManager fragmentManager, FragmentTransaction fragmentTransaction, MvxFragmentPresentationAttribute fragmentAttribute, string fragmentName, bool removeIsNeeded = false, bool forward = false)
        {
            fragmentAttribute = fragmentAttribute ?? DeqeueFragmentAttributeIfExist(fragmentName);

            if (fragmentAttribute != null)
            {
                if (!fragmentAttribute.EnterAnimation.Equals(int.MinValue) && !fragmentAttribute.ExitAnimation.Equals(int.MinValue))
                {
                    if (!fragmentAttribute.PopEnterAnimation.Equals(int.MinValue) && !fragmentAttribute.PopExitAnimation.Equals(int.MinValue))
                    {
                        fragmentTransaction.SetCustomAnimations(fragmentAttribute.EnterAnimation, fragmentAttribute.ExitAnimation, fragmentAttribute.PopEnterAnimation, fragmentAttribute.PopExitAnimation);
                    }
                    else
                    {
                        fragmentTransaction.SetCustomAnimations(fragmentAttribute.EnterAnimation, fragmentAttribute.ExitAnimation);
                    }
                }

                if (fragmentAttribute.TransitionStyle != int.MinValue)
                {
                    fragmentTransaction.SetTransitionStyle(fragmentAttribute.TransitionStyle);
                }
            }

            if ((FragmentsBackStack.LastOrDefault(x => x.Key == fragmentName)?.ViewModel as IBaseViewModel)?.VmNavigationType == NavigationType.PresentModal)
            {
                lock (this)
                {
                    _presentedModalFragments--;
                }
            }

            var oldFragment = fragmentManager.FindFragmentByTag(fragmentName);

            if (oldFragment != null)
            {
                if (!oldFragment.IsDetached)
                {
                    if (removeIsNeeded)
                    {
                        RemoveFragmentFromBackStack(fragmentName);

                        fragmentTransaction.Remove(oldFragment);
                    }
                    else
                    {
                        fragmentTransaction.Detach(oldFragment);
                    }
                }
                else if (removeIsNeeded)
                {
                    RemoveFragmentFromBackStack(fragmentName);

                    fragmentTransaction.Remove(oldFragment);
                }

                if (!forward)
                {
                    OnFragmentPopped(fragmentTransaction, oldFragment, null);
                }
            }
        }
        protected virtual void PushFragment(FragmentManager fragmentManager, FragmentTransaction fragmentTransaction, MvxFragmentPresentationAttribute fragmentAttribute, MvxViewModelRequest request, IMvxViewModel viewModel, string fragmentName, string fragmentTag = null)
        {
            if (string.IsNullOrEmpty(fragmentTag))
            {
                fragmentTag = fragmentName;
            }

            var newFragment = fragmentManager.FindFragmentByTag(fragmentTag);

            if (newFragment != null)
            {
                OnBeforeFragmentChanging(fragmentTransaction, newFragment, fragmentAttribute);

                if (newFragment.IsDetached)
                {
                    if (newFragment is IMvxFragmentView mvxFragment)
                    {
                        mvxFragment.ViewModel = viewModel;
                    }

                    if (request != null)
                    {
                        newFragment = SaveViewModelRequestInFragmentArguments(newFragment, request);
                    }

                    fragmentTransaction.Attach(newFragment);

                    OnFragmentChanging(fragmentTransaction, newFragment, fragmentAttribute);
                }
            }
            else if (fragmentAttribute != null)
            {
                var fragment = CreateFragment(fragmentAttribute, fragmentName);
                fragment.ViewModel = viewModel;

                Fragment fragmentView = null;

                if (request != null)
                {
                    fragmentView = SaveViewModelRequestInFragmentArguments(fragment.ToFragment(), request);
                }

                if (fragmentView != null)
                {
                    OnBeforeFragmentChanging(fragmentTransaction, fragmentView, fragmentAttribute);

                    fragmentTransaction.Add(fragmentAttribute.FragmentContentId, fragmentView, fragmentTag);

                    OnFragmentChanging(fragmentTransaction, fragmentView, fragmentAttribute);
                }
            }
        }
 protected virtual void OnBeforeNavigation(FragmentManager fragmentManager, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
 {
 }
Beispiel #15
0
 protected override bool CloseFragment(IMvxViewModel viewModel, MvxFragmentPresentationAttribute attribute)
 {
     _navigationViewModelManager.OnClose(viewModel);
     return(base.CloseFragment(viewModel, attribute));
 }