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) { }
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) { }
protected override bool CloseFragment(IMvxViewModel viewModel, MvxFragmentPresentationAttribute attribute) { _navigationViewModelManager.OnClose(viewModel); return(base.CloseFragment(viewModel, attribute)); }