summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/AppCompat
diff options
context:
space:
mode:
authorE.Z. Hart <hartez@users.noreply.github.com>2017-04-13 09:11:50 -0600
committerRui Marinho <me@ruimarinho.net>2017-04-13 16:11:50 +0100
commitaa1811126570b7d5e10c0473bad3b0dd0fb858eb (patch)
tree5128450f920dc05e3dcd9fe42dba076444193f09 /Xamarin.Forms.Platform.Android/AppCompat
parenta0affaafbd6d6721a5501384777959c7384d7ddb (diff)
downloadxamarin-forms-aa1811126570b7d5e10c0473bad3b0dd0fb858eb.tar.gz
xamarin-forms-aa1811126570b7d5e10c0473bad3b0dd0fb858eb.tar.bz2
xamarin-forms-aa1811126570b7d5e10c0473bad3b0dd0fb858eb.zip
Verify FragmentContainer created when queueing fragment transaction (Android) (#865)
* Add check for disposed MasterDetailContainer when queueing fragment transaction * Fix various ObjectDisposedExceptions when setting main page * Add check for legacy renderers when querying control properties
Diffstat (limited to 'Xamarin.Forms.Platform.Android/AppCompat')
-rw-r--r--Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs15
-rw-r--r--Xamarin.Forms.Platform.Android/AppCompat/Platform.cs20
2 files changed, 31 insertions, 4 deletions
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
index 0265cd3d..50840926 100644
--- a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
+++ b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
@@ -1,3 +1,4 @@
+using System;
using Android.App;
using Android.Content;
using Android.OS;
@@ -86,7 +87,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
// 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 =>
@@ -112,7 +113,17 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
_currentFragment = fragment;
- new Handler(Looper.MainLooper).PostAtFrontOfQueue(() => FragmentManager.ExecutePendingTransactions());
+ 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();
+ });
}
}
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs b/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs
index 0416ae3a..872bac77 100644
--- a/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs
+++ b/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Android.Content;
+using Android.OS;
using Android.Views;
using Android.Views.Animations;
using ARelativeLayout = Android.Widget.RelativeLayout;
using Xamarin.Forms.Internals;
+using Debug = System.Diagnostics.Debug;
namespace Xamarin.Forms.Platform.Android.AppCompat
{
@@ -219,12 +221,14 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
internal void SetPage(Page newRoot)
{
var layout = false;
+ List<IVisualElementRenderer> toDispose = null;
+
if (Page != null)
{
_renderer.RemoveAllViews();
- foreach (IVisualElementRenderer rootRenderer in _navModel.Roots.Select(Android.Platform.GetRenderer))
- rootRenderer.Dispose();
+ toDispose = _navModel.Roots.Select(Android.Platform.GetRenderer).ToList();
+
_navModel = new NavigationModel();
layout = true;
@@ -240,6 +244,18 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
AddChild(Page, layout);
Application.Current.NavigationProxy.Inner = this;
+
+ if (toDispose?.Count > 0)
+ {
+ // Queue up disposal of the previous renderers after the current layout updates have finished
+ new Handler(Looper.MainLooper).Post(() =>
+ {
+ foreach (IVisualElementRenderer rootRenderer in toDispose)
+ {
+ rootRenderer.Dispose();
+ }
+ });
+ }
}
void AddChild(Page page, bool layout = false)