2016-03-22 23:02:25 +03:00
|
|
|
using System;
|
|
|
|
using Android.OS;
|
|
|
|
using Android.Runtime;
|
|
|
|
using Android.Views;
|
2016-10-12 22:57:15 +03:00
|
|
|
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat;
|
2016-03-22 23:02:25 +03:00
|
|
|
using AView = Android.Views.View;
|
2016-09-27 13:51:22 +03:00
|
|
|
using Fragment = Android.Support.V4.App.Fragment;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
namespace Xamarin.Forms.Platform.Android.AppCompat
|
|
|
|
{
|
|
|
|
internal class FragmentContainer : Fragment
|
|
|
|
{
|
|
|
|
readonly WeakReference _pageReference;
|
|
|
|
|
2016-05-10 20:15:47 +03:00
|
|
|
Action<PageContainer> _onCreateCallback;
|
2016-03-22 23:02:25 +03:00
|
|
|
PageContainer _pageContainer;
|
|
|
|
IVisualElementRenderer _visualElementRenderer;
|
|
|
|
|
|
|
|
public FragmentContainer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public FragmentContainer(Page page) : this()
|
|
|
|
{
|
|
|
|
_pageReference = new WeakReference(page);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected FragmentContainer(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public Page Page => (Page)_pageReference?.Target;
|
|
|
|
|
2016-06-16 18:45:09 +03:00
|
|
|
IPageController PageController => Page as IPageController;
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
public static Fragment CreateInstance(Page page)
|
|
|
|
{
|
|
|
|
return new FragmentContainer(page) { Arguments = new Bundle() };
|
|
|
|
}
|
|
|
|
|
2016-05-10 20:15:47 +03:00
|
|
|
public void SetOnCreateCallback(Action<PageContainer> callback)
|
|
|
|
{
|
|
|
|
_onCreateCallback = callback;
|
|
|
|
}
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
public override AView OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
|
|
|
{
|
|
|
|
if (Page != null)
|
|
|
|
{
|
2017-10-09 20:51:55 +03:00
|
|
|
_visualElementRenderer = Android.Platform.CreateRenderer(Page, ChildFragmentManager, inflater.Context);
|
2016-03-22 23:02:25 +03:00
|
|
|
Android.Platform.SetRenderer(Page, _visualElementRenderer);
|
|
|
|
|
2017-10-09 20:51:55 +03:00
|
|
|
_pageContainer = new PageContainer(inflater.Context, _visualElementRenderer, true);
|
2016-05-10 20:15:47 +03:00
|
|
|
|
|
|
|
_onCreateCallback?.Invoke(_pageContainer);
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
return _pageContainer;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2016-09-27 13:51:22 +03:00
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
public override void OnDestroyView()
|
|
|
|
{
|
|
|
|
if (Page != null)
|
|
|
|
{
|
2016-06-27 18:20:47 +03:00
|
|
|
if (_visualElementRenderer != null)
|
2016-03-22 23:02:25 +03:00
|
|
|
{
|
2017-04-06 16:19:52 +03:00
|
|
|
if (_visualElementRenderer.View.Handle != IntPtr.Zero)
|
2016-06-27 18:20:47 +03:00
|
|
|
{
|
2017-04-06 16:19:52 +03:00
|
|
|
_visualElementRenderer.View.RemoveFromParent();
|
2016-06-27 18:20:47 +03:00
|
|
|
}
|
2016-03-22 23:02:25 +03:00
|
|
|
|
2016-06-27 18:20:47 +03:00
|
|
|
_visualElementRenderer.Dispose();
|
2016-03-22 23:02:25 +03:00
|
|
|
}
|
2016-06-27 18:20:47 +03:00
|
|
|
|
2016-09-27 13:51:22 +03:00
|
|
|
// We do *not* eagerly dispose of the _pageContainer here; doing so causes a memory leak
|
|
|
|
// if animated fragment transitions are enabled (it removes some info that the animation's
|
|
|
|
// onAnimationEnd handler requires to properly clean things up)
|
|
|
|
// Instead, we let the garbage collector pick it up later, when we can be sure it's safe
|
2016-06-27 18:20:47 +03:00
|
|
|
|
|
|
|
Page?.ClearValue(Android.Platform.RendererProperty);
|
2016-03-22 23:02:25 +03:00
|
|
|
}
|
|
|
|
|
2016-06-27 18:20:47 +03:00
|
|
|
_onCreateCallback = null;
|
2016-03-22 23:02:25 +03:00
|
|
|
_visualElementRenderer = null;
|
|
|
|
|
|
|
|
base.OnDestroyView();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void OnHiddenChanged(bool hidden)
|
|
|
|
{
|
|
|
|
base.OnHiddenChanged(hidden);
|
|
|
|
|
|
|
|
if (Page == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (hidden)
|
2016-06-27 18:20:47 +03:00
|
|
|
PageController?.SendDisappearing();
|
2016-03-22 23:02:25 +03:00
|
|
|
else
|
2016-06-27 18:20:47 +03:00
|
|
|
PageController?.SendAppearing();
|
2016-03-22 23:02:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public override void OnPause()
|
|
|
|
{
|
2017-03-14 14:57:32 +03:00
|
|
|
bool shouldSendEvent = Application.Current.OnThisPlatform().GetSendDisappearingEventOnPause();
|
2016-10-12 22:57:15 +03:00
|
|
|
if (shouldSendEvent)
|
2017-03-14 14:57:32 +03:00
|
|
|
SendLifecycleEvent(false);
|
2016-09-30 21:57:28 +03:00
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
base.OnPause();
|
|
|
|
}
|
2016-10-12 22:57:15 +03:00
|
|
|
|
2016-03-28 14:09:51 +03:00
|
|
|
public override void OnResume()
|
|
|
|
{
|
2017-03-14 14:57:32 +03:00
|
|
|
bool shouldSendEvent = Application.Current.OnThisPlatform().GetSendAppearingEventOnResume();
|
2016-10-12 22:57:15 +03:00
|
|
|
if (shouldSendEvent)
|
2017-03-14 14:57:32 +03:00
|
|
|
SendLifecycleEvent(true);
|
2016-09-30 21:57:28 +03:00
|
|
|
|
2016-03-28 14:09:51 +03:00
|
|
|
base.OnResume();
|
|
|
|
}
|
2017-03-14 14:57:32 +03:00
|
|
|
|
|
|
|
void SendLifecycleEvent(bool isAppearing)
|
|
|
|
{
|
|
|
|
var masterDetailPage = Application.Current.MainPage as MasterDetailPage;
|
|
|
|
var pageContainer = (masterDetailPage != null ? masterDetailPage.Detail : Application.Current.MainPage) as IPageContainer<Page>;
|
|
|
|
Page currentPage = pageContainer?.CurrentPage;
|
|
|
|
|
|
|
|
if(!(currentPage == null || currentPage == PageController))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (isAppearing && UserVisibleHint)
|
|
|
|
PageController?.SendAppearing();
|
|
|
|
else if(!isAppearing)
|
|
|
|
PageController?.SendDisappearing();
|
|
|
|
}
|
2016-03-22 23:02:25 +03:00
|
|
|
}
|
|
|
|
}
|