diff --git a/.gitignore b/.gitignore
index 10f16da..b0eb4b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
## files generated by popular Visual Studio add-ons.
.vs/
+mono_crash.*
# User-specific files
*.suo
diff --git a/AiForms.Dialogs.Android/AiForms.Dialogs.Android.csproj b/AiForms.Dialogs.Android/AiForms.Dialogs.Android.csproj
index b6f96e4..a9caea1 100644
--- a/AiForms.Dialogs.Android/AiForms.Dialogs.Android.csproj
+++ b/AiForms.Dialogs.Android/AiForms.Dialogs.Android.csproj
@@ -161,7 +161,7 @@
- {7FAEA2AA-1832-4CAF-B0BA-4501F377269D}
+ {0BDF7090-FE73-49E6-B554-B2DA240768BB}
AiForms.Dialogs.Abstractions
diff --git a/AiForms.Dialogs.Android/DefaultLoading.cs b/AiForms.Dialogs.Android/DefaultLoading.cs
index 5c0cf7c..a1087c6 100644
--- a/AiForms.Dialogs.Android/DefaultLoading.cs
+++ b/AiForms.Dialogs.Android/DefaultLoading.cs
@@ -41,9 +41,10 @@ public async Task StartAsync(Func, Task> action, string messag
public void Show(string message = null, bool isCurrentScope = false)
{
+ IsDialogShownTcs = new TaskCompletionSource();
OnceInitializeAction?.Invoke();
- var payload = new LoadingDialogPayload(ContentView);
+ var payload = new LoadingDialogPayload(ContentView,IsDialogShownTcs);
var bundle = new Bundle();
bundle.PutSerializable(LoadingDialogPayload.PayloadKey, payload);
@@ -56,7 +57,8 @@ public void Show(string message = null, bool isCurrentScope = false)
}
public void Hide()
- {
+ {
+
if (Progress != null)
{
Progress.ProgressChanged -= ProgressAction;
@@ -70,9 +72,9 @@ public void Hide()
Task.Run(async () =>
{
- // Wait a bit for ensuring that the dialog is created.
+ // Wait for ensuring that the dialog is created.
// Because it sometimes crashes or freezes when executing a very short process.
- await Task.Delay(50);
+ await IsDialogShownTcs.Task;
var dialog = FragmentManager.FindFragmentByTag(LoadingImplementation.LoadingDialogTag);
dialog?.Dismiss();
ContentView.RemoveFromParent();
diff --git a/AiForms.Dialogs.Android/DialogImplementation.cs b/AiForms.Dialogs.Android/DialogImplementation.cs
index 1e2e71a..ef4a187 100644
--- a/AiForms.Dialogs.Android/DialogImplementation.cs
+++ b/AiForms.Dialogs.Android/DialogImplementation.cs
@@ -7,13 +7,8 @@ namespace AiForms.Dialogs
[Android.Runtime.Preserve(AllMembers = true)]
public class DialogImplementation : IDialog
{
- public static readonly string ExtraDialogTag = "ExtraDialog";
- internal ExtraPlatformDialog ExtraDialog;
- FragmentManager FragmentManager => Dialogs.FragmentManager;
-
public DialogImplementation()
{
- ExtraDialog = new ExtraPlatformDialog();
}
public IReusableDialog Create(object viewModel = null) where TView : DialogView
@@ -30,8 +25,6 @@ public IReusableDialog Create(DialogView view, object viewModel = null)
public async Task ShowAsync(object viewModel = null) where TView : DialogView
{
- if (IsRunning()) return false;
-
using (var dlg = Create(viewModel))
{
return await dlg.ShowAsync();
@@ -40,19 +33,10 @@ public async Task ShowAsync(object viewModel = null) where TView :
public async Task ShowAsync(DialogView view, object viewModel = null)
{
- if (IsRunning()) return false;
-
using (var dlg = Create(view, viewModel))
{
return await dlg.ShowAsync();
}
}
-
- bool IsRunning()
- {
- var dialog = Dialogs.FragmentManager.FindFragmentByTag(DialogImplementation.ExtraDialogTag);
- return dialog != null;
- }
-
}
}
diff --git a/AiForms.Dialogs.Android/ExtraPlatformDialog.cs b/AiForms.Dialogs.Android/ExtraPlatformDialog.cs
index 0d3278f..29ffc5e 100644
--- a/AiForms.Dialogs.Android/ExtraPlatformDialog.cs
+++ b/AiForms.Dialogs.Android/ExtraPlatformDialog.cs
@@ -17,6 +17,11 @@ public class ExtraPlatformDialog : Android.App.DialogFragment
DialogView _dialogView;
ViewGroup _contentView;
+ public ExtraPlatformDialog() { }
+
+ // System Required!
+ public ExtraPlatformDialog(IntPtr handle, JniHandleOwnership transfer) :base(handle,transfer) { }
+
public override Android.App.Dialog OnCreateDialog(Bundle savedInstanceState)
{
base.OnCreateDialog(savedInstanceState);
diff --git a/AiForms.Dialogs.Android/LoadingBase.cs b/AiForms.Dialogs.Android/LoadingBase.cs
index ca83fb4..2d94553 100644
--- a/AiForms.Dialogs.Android/LoadingBase.cs
+++ b/AiForms.Dialogs.Android/LoadingBase.cs
@@ -16,6 +16,8 @@ public class LoadingBase:IDisposable
protected ViewGroup ContentView;
+ protected TaskCompletionSource IsDialogShownTcs;
+
public LoadingBase(LoadingPlatformDialog loadingDialog)
{
PlatformDialog = loadingDialog;
diff --git a/AiForms.Dialogs.Android/LoadingDialogPayload.cs b/AiForms.Dialogs.Android/LoadingDialogPayload.cs
index 49ca53b..436dd80 100644
--- a/AiForms.Dialogs.Android/LoadingDialogPayload.cs
+++ b/AiForms.Dialogs.Android/LoadingDialogPayload.cs
@@ -1,4 +1,5 @@
-using AiForms.Dialogs.Abstractions;
+using System.Threading.Tasks;
+using AiForms.Dialogs.Abstractions;
using Android.Views;
using Java.IO;
@@ -10,11 +11,13 @@ public class LoadingDialogPayload : Java.Lang.Object, ISerializable
public static readonly string PayloadKey = "loadingDialogPayload";
public LoadingView LoadingView { get; set; }
public ViewGroup ContentView { get; set; }
+ public TaskCompletionSource IsShownTcs { get; set; }
- public LoadingDialogPayload(ViewGroup contentView, LoadingView loadingView = null)
+ public LoadingDialogPayload(ViewGroup contentView, TaskCompletionSource tcs, LoadingView loadingView = null)
{
LoadingView = loadingView;
ContentView = contentView;
+ IsShownTcs = tcs;
}
protected override void Dispose(bool disposing)
@@ -23,6 +26,7 @@ protected override void Dispose(bool disposing)
{
LoadingView = null;
ContentView = null;
+ IsShownTcs = null;
}
base.Dispose(disposing);
}
diff --git a/AiForms.Dialogs.Android/LoadingPlatformDialog.cs b/AiForms.Dialogs.Android/LoadingPlatformDialog.cs
index ed5a9ed..ac36237 100644
--- a/AiForms.Dialogs.Android/LoadingPlatformDialog.cs
+++ b/AiForms.Dialogs.Android/LoadingPlatformDialog.cs
@@ -25,6 +25,7 @@ public override Android.App.Dialog OnCreateDialog(Bundle savedInstanceState)
_loadingView = payload.LoadingView;
_contentView = payload.ContentView;
+ var isShowTcs = payload.IsShownTcs;
payload.Dispose();
@@ -36,7 +37,15 @@ public override Android.App.Dialog OnCreateDialog(Bundle savedInstanceState)
DestroyTcs = new TaskCompletionSource();
- return dialog;
+ try
+ {
+
+ return dialog;
+ }
+ finally
+ {
+ isShowTcs.SetResult(true);
+ }
}
public override void OnStart()
diff --git a/AiForms.Dialogs.Android/ReusableDialog.cs b/AiForms.Dialogs.Android/ReusableDialog.cs
index 5eb38a6..069a243 100644
--- a/AiForms.Dialogs.Android/ReusableDialog.cs
+++ b/AiForms.Dialogs.Android/ReusableDialog.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using AiForms.Dialogs.Abstractions;
using Android.App;
@@ -16,18 +17,18 @@ namespace AiForms.Dialogs
[Android.Runtime.Preserve(AllMembers = true)]
public class ReusableDialog:Java.Lang.Object, IReusableDialog, View.IOnKeyListener
{
- DialogImplementation _extraDialog;
- ExtraPlatformDialog _platformDialog => _extraDialog.ExtraDialog;
+ ExtraPlatformDialog _platformDialog;
FragmentManager FragmentManager => Dialogs.FragmentManager;
DialogView _dlgView;
IVisualElementRenderer _renderer;
ViewGroup _contentView;
Action OnceInitializeAction;
+ Guid _guid;
public ReusableDialog(DialogView view)
{
- _dlgView = view;
- _extraDialog = Dialog.Instance as DialogImplementation;
+ _dlgView = view;
+ _guid = Guid.NewGuid();
// Because the process can't be executed until application completely loads,
// set the action here to execute later on.
@@ -125,7 +126,7 @@ void Initialize()
public async Task ShowAsync()
{
- var dialog = FragmentManager.FindFragmentByTag(DialogImplementation.ExtraDialogTag);
+ var dialog = FragmentManager.FindFragmentByTag(_guid.ToString());
if (dialog != null)
{
return false;
@@ -148,7 +149,7 @@ async void complete(object sender, EventArgs e)
_dlgView.RunDismissalAnimation();
await Dismiss();
tcs.SetResult(true);
- };
+ }
_dlgView.DialogNotifierInternal.Canceled += cancel;
_dlgView.DialogNotifierInternal.Completed += complete;
@@ -157,8 +158,9 @@ async void complete(object sender, EventArgs e)
var payload = new ExtraDialogPayload(_dlgView,_contentView);
var bundle = new Bundle();
bundle.PutSerializable("extraDialogPayload", payload);
+ _platformDialog = new ExtraPlatformDialog();
_platformDialog.Arguments = bundle;
- _platformDialog.Show(FragmentManager, DialogImplementation.ExtraDialogTag);
+ _platformDialog.Show(FragmentManager, _guid.ToString());
try
{
@@ -171,6 +173,7 @@ async void complete(object sender, EventArgs e)
_dlgView.TearDown();
payload.Dispose();
bundle.Dispose();
+
}
}
@@ -190,7 +193,7 @@ protected override void Dispose(bool disposing)
if (!_renderer.View.IsDisposed())
{
_renderer.View.Dispose();
- }
+ }
_contentView.Dispose();
_contentView = null;
@@ -198,8 +201,6 @@ protected override void Dispose(bool disposing)
_renderer.Dispose();
_renderer = null;
- _extraDialog = null;
-
OnceInitializeAction = null;
}
base.Dispose(disposing);
@@ -256,9 +257,11 @@ void handler(object sender, Animation.AnimationEndEventArgs e)
await tcs.Task;
anim.AnimationEnd -= handler;
- var dialog = FragmentManager.FindFragmentByTag(DialogImplementation.ExtraDialogTag);
+ var dialog = FragmentManager.FindFragmentByTag(_guid.ToString());
dialog.Dismiss();
_contentView.RemoveFromParent();
+ _platformDialog.Dispose();
+ _platformDialog = null;
await Task.Delay(250); // wait for a bit time until the dialog is completely released.
}
diff --git a/AiForms.Dialogs.Android/ReusableLoading.cs b/AiForms.Dialogs.Android/ReusableLoading.cs
index b6a9f19..342b4b2 100644
--- a/AiForms.Dialogs.Android/ReusableLoading.cs
+++ b/AiForms.Dialogs.Android/ReusableLoading.cs
@@ -66,9 +66,10 @@ public async Task StartAsync(Func, Task> action, bool isCurren
void ShowInner()
{
+ IsDialogShownTcs = new TaskCompletionSource();
OnceInitializeAction?.Invoke();
- var payload = new LoadingDialogPayload(ContentView, _loadingView);
+ var payload = new LoadingDialogPayload(ContentView,IsDialogShownTcs, _loadingView);
var bundle = new Bundle();
bundle.PutSerializable(LoadingDialogPayload.PayloadKey, payload);
@@ -95,9 +96,9 @@ public void Hide()
Task.Run(async () =>
{
- // Wait a bit for ensuring that the dialog is created.
+ // Wait for ensuring that the dialog is created.
// Because it sometimes crashes or freezes when executing a very short process.
- await Task.Delay(50);
+ await IsDialogShownTcs.Task;
var dialog = FragmentManager.FindFragmentByTag(LoadingImplementation.LoadingDialogTag);
dialog?.Dismiss();
ContentView.RemoveFromParent();
diff --git a/Sample/Sample.iOS/Info.plist b/Sample/Sample.iOS/Info.plist
index d2c8b2a..0213a9e 100644
--- a/Sample/Sample.iOS/Info.plist
+++ b/Sample/Sample.iOS/Info.plist
@@ -3,7 +3,7 @@
CFBundleDisplayName
- Sample
+ Dialogs
CFBundleShortVersionString
1.0
CFBundleVersion
@@ -39,8 +39,8 @@
XSAppIconAssets
Resources/Images.xcassets/AppIcons.appiconset
CFBundleName
- Sample
+ Dialogs
CFBundleIdentifier
- jp.kamusoft.sample
+ jp.kamusoft.dialogs
diff --git a/Sample/Sample/ViewModels/DialogTestViewModel.cs b/Sample/Sample/ViewModels/DialogTestViewModel.cs
index 1759a2d..0ba259a 100644
--- a/Sample/Sample/ViewModels/DialogTestViewModel.cs
+++ b/Sample/Sample/ViewModels/DialogTestViewModel.cs
@@ -76,7 +76,7 @@ string GetHAlignString()
string GetVAlignString()
{
- switch (HorizontalLayoutAlignment)
+ switch (VerticalLayoutAlignment)
{
case LayoutAlignment.Start:
return "Top";
diff --git a/Sample/Sample/ViewModels/MainPageViewModel.cs b/Sample/Sample/ViewModels/MainPageViewModel.cs
index 55ec679..237a586 100644
--- a/Sample/Sample/ViewModels/MainPageViewModel.cs
+++ b/Sample/Sample/ViewModels/MainPageViewModel.cs
@@ -49,23 +49,23 @@ public MainPageViewModel(MyIndicatorView myIndicatorView)
var loadingFlg = false;
LoadingCommand.Subscribe(async _ =>
{
- Loading.Instance.Show();
- await Task.Delay(1);
- Loading.Instance.Hide();
-
- //await Loading.Instance.StartAsync(async progress => {
- // //await Task.Delay(1);
- // progress.Report(0d);
- // for (var i = 0; i < 100; i++)
- // {
- // if (i == 50)
- // {
- // Loading.Instance.SetMessage("Soon...");
- // }
- // await Task.Delay(50);
- // progress.Report((i + 1) * 0.01d);
- // }
- //},null,loadingFlg).ConfigureAwait(false);
+ //Loading.Instance.Show();
+ //await Task.Delay(1);
+ //Loading.Instance.Hide();
+
+ await Loading.Instance.StartAsync(async progress => {
+ //await Task.Delay(1);
+ progress.Report(0d);
+ for (var i = 0; i < 100; i++)
+ {
+ if (i == 50)
+ {
+ Loading.Instance.SetMessage("Soon...");
+ }
+ await Task.Delay(25);
+ progress.Report((i + 1) * 0.01d);
+ }
+ },null,loadingFlg).ConfigureAwait(false);
loadingFlg = !loadingFlg;
});
@@ -83,11 +83,11 @@ public MainPageViewModel(MyIndicatorView myIndicatorView)
});
await customLoading.StartAsync(async p =>
{
- //await Task.Delay(1);
+ await Task.Delay(1);
p.Report(0d);
for (var i = 0; i < 100; i++)
{
- await Task.Delay(50);
+ await Task.Delay(25);
p.Report((i + 1) * 0.01d);
}
});
diff --git a/Sample/Sample/ViewModels/SurveyPageViewModel.cs b/Sample/Sample/ViewModels/SurveyPageViewModel.cs
new file mode 100644
index 0000000..bef1f56
--- /dev/null
+++ b/Sample/Sample/ViewModels/SurveyPageViewModel.cs
@@ -0,0 +1,26 @@
+using System;
+using AiForms.Dialogs.Abstractions;
+using Prism.Mvvm;
+using Reactive.Bindings;
+using Sample.Views;
+using Sample.Views.Dialogs;
+
+namespace Sample.ViewModels
+{
+ public class SurveyPageViewModel:BindableBase
+ {
+ public ReactiveCommand ShowDialogCommand { get; } = new ReactiveCommand();
+ public SurveyPageViewModel()
+ {
+ var dialog = AiForms.Dialogs.Dialog.Instance;
+ ShowDialogCommand.Subscribe(async _ =>
+ {
+ var ret = await dialog.ShowAsync();
+ if (ret)
+ {
+ //await dialog.ShowAsync();
+ }
+ });
+ }
+ }
+}
diff --git a/Sample/Sample/Views/Dialogs/TestDialog.xaml b/Sample/Sample/Views/Dialogs/TestDialog.xaml
new file mode 100644
index 0000000..b79fe1d
--- /dev/null
+++ b/Sample/Sample/Views/Dialogs/TestDialog.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/Sample/Sample/Views/Dialogs/TestDialog.xaml.cs b/Sample/Sample/Views/Dialogs/TestDialog.xaml.cs
new file mode 100644
index 0000000..3effdf9
--- /dev/null
+++ b/Sample/Sample/Views/Dialogs/TestDialog.xaml.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using AiForms.Dialogs.Abstractions;
+using Xamarin.Forms;
+
+namespace Sample.Views.Dialogs
+{
+ public partial class TestDialog : DialogView
+ {
+ public TestDialog()
+ {
+ InitializeComponent();
+ }
+
+ void Button_Clicked(System.Object sender, System.EventArgs e)
+ {
+ Device.BeginInvokeOnMainThread(() =>
+ {
+ //(this.Parent as Page).DisplayAlert("", "Hoge","OK");
+ //(this.Parent as Page).DisplayAlert("", "Fuga", "OK");
+ AiForms.Dialogs.Dialog.Instance.ShowAsync();
+ });
+ //DialogNotifier.Complete();
+
+ }
+
+ public override void Destroy()
+ {
+
+ }
+ }
+}
diff --git a/Sample/Sample/Views/IndexPage.xaml b/Sample/Sample/Views/IndexPage.xaml
index a79a10a..05b0792 100644
--- a/Sample/Sample/Views/IndexPage.xaml
+++ b/Sample/Sample/Views/IndexPage.xaml
@@ -10,5 +10,6 @@
+
diff --git a/Sample/Sample/Views/SurveyPage.xaml b/Sample/Sample/Views/SurveyPage.xaml
new file mode 100644
index 0000000..65638d7
--- /dev/null
+++ b/Sample/Sample/Views/SurveyPage.xaml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/Sample/Sample/Views/SurveyPage.xaml.cs b/Sample/Sample/Views/SurveyPage.xaml.cs
new file mode 100644
index 0000000..3fe52d0
--- /dev/null
+++ b/Sample/Sample/Views/SurveyPage.xaml.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+
+using Xamarin.Forms;
+
+namespace Sample.Views
+{
+ public partial class SurveyPage : ContentPage
+ {
+ public SurveyPage()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/nuget/AzurePipelines.nuspec b/nuget/AzurePipelines.nuspec
index 8115ab7..396df21 100644
--- a/nuget/AzurePipelines.nuspec
+++ b/nuget/AzurePipelines.nuspec
@@ -14,7 +14,9 @@
-First Release.
+## Changes
+
+* [Dialog][Android] Nested dialogs are now supported. #8
Xamarin.Forms Xamarin dialog toast loading progress popup xaml netstandard ios android
en-US