summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
diff options
context:
space:
mode:
authorE.Z. Hart <hartez@users.noreply.github.com>2016-05-10 11:15:47 -0600
committerJason Smith <jason.smith@xamarin.com>2016-05-10 10:15:47 -0700
commit5acafedb8e3e2ace8e66f9ff20655d5d96e8ed97 (patch)
treec816ea1127275953bcc458315e1714fd0cb17003 /Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
parentd4a5bb8dfcb39949451fe0e5390a684f116cc288 (diff)
downloadxamarin-forms-5acafedb8e3e2ace8e66f9ff20655d5d96e8ed97.tar.gz
xamarin-forms-5acafedb8e3e2ace8e66f9ff20655d5d96e8ed97.tar.bz2
xamarin-forms-5acafedb8e3e2ace8e66f9ff20655d5d96e8ed97.zip
[Android] Isolate fragment management for children of MasterDetailPage (#136)
* Isolate fragment management for children of MasterDetailPage in AppCompat If a MasterDetailPage hosts NavigationPages or TabbedPages in either the Master or Detail sections, wrap those pages in their own Fragment (and ChildFragmentManager) to isolate their Fragment management operations and avoid recursive entry into the executePendingTransactions method Also fix a disposal bug in the custom MDP renderer in Control Gallery * Remove MDP Split setting that breaks test on iPad
Diffstat (limited to 'Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs')
-rw-r--r--Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs92
1 files changed, 92 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
new file mode 100644
index 00000000..de167906
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs
@@ -0,0 +1,92 @@
+using Android.App;
+using Android.Content;
+using Fragment = Android.Support.V4.App.Fragment;
+using FragmentManager = Android.Support.V4.App.FragmentManager;
+using FragmentTransaction = Android.Support.V4.App.FragmentTransaction;
+
+namespace Xamarin.Forms.Platform.Android.AppCompat
+{
+ internal class MasterDetailContainer : Xamarin.Forms.Platform.Android.MasterDetailContainer, IManageFragments
+ {
+ PageContainer _pageContainer;
+ FragmentManager _fragmentManager;
+ readonly bool _isMaster;
+ readonly MasterDetailPage _parent;
+
+ public MasterDetailContainer(MasterDetailPage parent, bool isMaster, Context context) : base(parent, isMaster, context)
+ {
+ Id = FormsAppCompatActivity.GetUniqueId();
+ _parent = parent;
+ _isMaster = isMaster;
+ }
+
+ FragmentManager FragmentManager => _fragmentManager ?? (_fragmentManager = ((FormsAppCompatActivity)Context).SupportFragmentManager);
+
+ protected override void OnLayout(bool changed, int l, int t, int r, int b)
+ {
+ base.OnLayout(changed, l, t, r, b);
+
+ // If we're using a PageContainer (i.e., we've wrapped our contents in a Fragment),
+ // Make sure that it gets laid out
+ if (_pageContainer != null)
+ {
+ if (_isMaster)
+ {
+ var width = (int)Context.ToPixels(_parent.MasterBounds.Width);
+ // When the base class computes the size of the Master container, it starts at the top of the
+ // screen and adds padding (_parent.MasterBounds.Top) to leave room for the status bar
+ // When this container is laid out, it's already starting from the adjusted y value of the parent,
+ // so we subtract _parent.MasterBounds.Top from our starting point (to get 0) and add it to the
+ // bottom (so the master page stretches to the bottom of the screen)
+ var height = (int)Context.ToPixels(_parent.MasterBounds.Height + _parent.MasterBounds.Top);
+ _pageContainer.Layout(0, 0, width, height);
+ }
+ else
+ {
+ _pageContainer.Layout(l, t, r, b);
+ }
+
+ _pageContainer.Child.UpdateLayout();
+ }
+ }
+
+ 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();
+ }
+ }
+
+ public void SetFragmentManager(FragmentManager fragmentManager)
+ {
+ if (_fragmentManager == null)
+ _fragmentManager = fragmentManager;
+ }
+ }
+} \ No newline at end of file