protected MvxCachingFragmentActivity(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { BindingContext = new MvxAndroidBindingContext(this, this); this.AddEventListeners(); FragmentCacheConfiguration = new FragmentCacheConfiguration(); }
protected override void OnCreate(Bundle bundle) { // Prevents crash when activity in background with history enable is reopened after // Android does some auto memory management. var setup = MvxAndroidSetupSingleton.EnsureSingletonAvailable(this); setup.EnsureInitialized(); base.OnCreate(bundle); if (bundle == null) { HandleIntent(Intent); } else { IMvxJsonConverter serializer; if (!Mvx.TryResolve(out serializer)) { Mvx.Trace( "Could not resolve IMvxJsonConverter, it is going to be hard to create ViewModel cache"); return; } FragmentCacheConfiguration.RestoreCacheConfiguration(bundle, serializer); // Gabriel has blown his trumpet. Ressurect Fragments from the dead RestoreFragmentsCache(); RestoreViewModelsFromBundle(serializer, bundle); } }
protected IMvxCachedFragmentInfo GetFragmentInfoByTag(string tag) { IMvxCachedFragmentInfo fragInfo; FragmentCacheConfiguration.TryGetValue(tag, out fragInfo); if (fragInfo == null) throw new MvxException("Could not find tag: {0} in cache, you need to register it first.", tag); return fragInfo; }
/// <summary> /// Show Fragment with a specific tag at a specific placeholder /// </summary> /// <param name="tag">The tag for the fragment to lookup</param> /// <param name="contentId">Where you want to show the Fragment</param> /// <param name="bundle">Bundle which usually contains a Serialized MvxViewModelRequest</param> /// <param name="forceAddToBackStack">If you want to force add the fragment to the backstack so on backbutton it will go back to it. Note: This will override IMvxCachedFragmentInfo.AddToBackStack configuration.</param> /// <param name="forceReplaceFragment">Force replace a fragment with the same tag at the same contentid</param> protected void ShowFragment(string tag, int contentId, Bundle bundle = null, bool forceAddToBackStack = false, bool forceReplaceFragment = false) { IMvxCachedFragmentInfo fragInfo; FragmentCacheConfiguration.TryGetValue(tag, out fragInfo); if (fragInfo == null) { throw new MvxException("Could not find tag: {0} in cache, you need to register it first.", tag); } // We shouldn't replace the current fragment unless we really need to. var shouldReplaceCurrentFragment = forceReplaceFragment || ShouldReplaceCurrentFragment(contentId, tag); if (!shouldReplaceCurrentFragment) { return; } var ft = SupportFragmentManager.BeginTransaction(); OnBeforeFragmentChanging(fragInfo, ft); fragInfo.ContentId = contentId; //If we already have a previously created fragment, we only need to send the new parameters if (fragInfo.CachedFragment != null) { fragInfo.CachedFragment.Arguments.Clear(); fragInfo.CachedFragment.Arguments.PutAll(bundle); } else { //Otherwise, create one and cache it fragInfo.CachedFragment = Fragment.Instantiate(this, FragmentJavaName(fragInfo.FragmentType), bundle); OnFragmentCreated(fragInfo, ft); } ft.Replace(fragInfo.ContentId, fragInfo.CachedFragment, fragInfo.Tag); if (fragInfo.AddToBackStack || forceAddToBackStack) { ft.AddToBackStack(fragInfo.Tag); } OnFragmentChanging(fragInfo, ft); ft.Commit(); //TODO: manager crashes sometimes SupportFragmentManager.ExecutePendingTransactions(); OnFragmentChanged(fragInfo); }
protected override void OnSaveInstanceState(Bundle outState) { base.OnSaveInstanceState(outState); IMvxJsonConverter ser; if (FragmentCacheConfiguration.HasAnyFragmentsRegisteredToCache && Mvx.TryResolve(out ser)) { FragmentCacheConfiguration.SaveFragmentCacheConfigurationState(outState, ser); var typesForKeys = CreateFragmentTypesDictionary(outState); if (typesForKeys == null) return; var json = ser.SerializeObject(typesForKeys); outState.PutString(SavedFragmentTypesKey, json); } }
protected override void OnPostCreate(Bundle savedInstanceState) { base.OnPostCreate(savedInstanceState); if (savedInstanceState == null) { return; } IMvxJsonConverter serializer; if (!Mvx.TryResolve(out serializer)) { Mvx.Trace( "Could not resolve IMvxJsonConverter, it is going to be hard to create ViewModel cache"); return; } FragmentCacheConfiguration.RestoreCacheConfiguration(savedInstanceState, serializer); // Gabriel has blown his trumpet. Ressurect Fragments from the dead. RestoreFragmentsCache(); RestoreViewModelsFromBundle(serializer, savedInstanceState); }
protected override void OnCreate(Bundle bundle) { // Prevents crash when activity in background with history enable is reopened after // Android does some auto memory management. var setup = MvxAndroidSetupSingleton.EnsureSingletonAvailable(this); setup.EnsureInitialized(); base.OnCreate(bundle); var rootView = Window.DecorView.RootView; EventHandler onGlobalLayout = null; onGlobalLayout = (sender, args) => { rootView.ViewTreeObserver.GlobalLayout -= onGlobalLayout; ViewModel.Appeared(); }; rootView.ViewTreeObserver.GlobalLayout += onGlobalLayout; if (bundle == null) HandleIntent(Intent); else { IMvxJsonConverter serializer; if (!Mvx.TryResolve(out serializer)) { Mvx.Trace( "Could not resolve IMvxJsonConverter, it is going to be hard to create ViewModel cache"); return; } FragmentCacheConfiguration.RestoreCacheConfiguration(bundle, serializer); // Gabriel has blown his trumpet. Ressurect Fragments from the dead RestoreFragmentsCache(); RestoreViewModelsFromBundle(serializer, bundle); } }
/// <summary> /// Show Fragment with a specific tag at a specific placeholder /// </summary> /// <param name="tag">The tag for the fragment to lookup</param> /// <param name="contentId">Where you want to show the Fragment</param> /// <param name="bundle">Bundle which usually contains a Serialized MvxViewModelRequest</param> /// <param name="forceAddToBackStack">If you want to force add the fragment to the backstack so on backbutton it will go back to it. Note: This will override IMvxCachedFragmentInfo.AddToBackStack configuration.</param> /// <param name="forceReplaceFragment">If you want the fragment to be re-created</param> protected virtual void ShowFragment(string tag, int contentId, Bundle bundle, bool forceAddToBackStack = false, bool forceReplaceFragment = false) { IMvxCachedFragmentInfo fragInfo; FragmentCacheConfiguration.TryGetValue(tag, out fragInfo); IMvxCachedFragmentInfo currentFragInfo = null; var currentFragment = SupportFragmentManager.FindFragmentById(contentId); if (currentFragment != null) { FragmentCacheConfiguration.TryGetValue(currentFragment.Tag, out currentFragInfo); } if (fragInfo == null) { throw new MvxException("Could not find tag: {0} in cache, you need to register it first.", tag); } // We shouldn't replace the current fragment unless we really need to. FragmentReplaceMode fragmentReplaceMode = FragmentReplaceMode.ReplaceFragmentAndViewModel; if (!forceReplaceFragment) { fragmentReplaceMode = ShouldReplaceCurrentFragment(fragInfo, currentFragInfo, bundle); } if (fragmentReplaceMode == FragmentReplaceMode.NoReplace) { return; } var ft = SupportFragmentManager.BeginTransaction(); OnBeforeFragmentChanging(fragInfo, ft); fragInfo.ContentId = contentId; //If we already have a previously created fragment, we only need to send the new parameters if (fragInfo.CachedFragment != null && fragmentReplaceMode == FragmentReplaceMode.ReplaceFragment) { ((Android.Support.V4.App.Fragment)fragInfo.CachedFragment).Arguments.Clear(); ((Android.Support.V4.App.Fragment)fragInfo.CachedFragment).Arguments.PutAll(bundle); } else { //Otherwise, create one and cache it fragInfo.CachedFragment = Android.Support.V4.App.Fragment.Instantiate(this, FragmentJavaName(fragInfo.FragmentType), bundle) as IMvxFragmentView; OnFragmentCreated(fragInfo, ft); } currentFragment = fragInfo.CachedFragment as Android.Support.V4.App.Fragment; ft.Replace(fragInfo.ContentId, fragInfo.CachedFragment as Android.Support.V4.App.Fragment, fragInfo.Tag); //if replacing ViewModel then clear the cache after the fragment //has been added to the transaction so that the Tag property is not null //and the UniqueImmutableCacheTag property (if not overridden) has the correct value if (fragmentReplaceMode == FragmentReplaceMode.ReplaceFragmentAndViewModel) { var cache = Mvx.GetSingleton <IMvxMultipleViewModelCache>(); cache.GetAndClear(fragInfo.ViewModelType, GetTagFromFragment(fragInfo.CachedFragment as Android.Support.V4.App.Fragment)); } if ((currentFragment != null && fragInfo.AddToBackStack) || forceAddToBackStack) { ft.AddToBackStack(fragInfo.Tag); } OnFragmentChanging(fragInfo, ft); ft.Commit(); SupportFragmentManager.ExecutePendingTransactions(); OnFragmentChanged(fragInfo); }
protected MvxCachingFragmentActivity() { FragmentCacheConfiguration = new FragmentCacheConfiguration(); }