Huge help thanks to AswinPG who was able to parse out the errors here.
This is just a commit for tonight, i'll keep adding more soon
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
using AsyncAwaitBestPractices;
|
||||
using System.Windows.Input;
|
||||
|
||||
using AsyncAwaitBestPractices;
|
||||
|
||||
using Mopups.Animations;
|
||||
using Mopups.Animations.Base;
|
||||
using Mopups.Enums;
|
||||
using Mopups.Services;
|
||||
|
||||
namespace Mopups.Pages;
|
||||
@@ -9,6 +15,48 @@ public partial class PopupPage : ContentPage
|
||||
|
||||
public static readonly BindableProperty CloseWhenBackgroundIsClickedProperty = BindableProperty.Create(nameof(CloseWhenBackgroundIsClicked), typeof(bool), typeof(PopupPage), true);
|
||||
|
||||
public static readonly BindableProperty IsAnimationEnabledProperty = BindableProperty.Create(nameof(IsAnimationEnabled), typeof(bool), typeof(PopupPage), true);
|
||||
|
||||
public bool IsAnimationEnabled
|
||||
{
|
||||
get { return (bool)GetValue(IsAnimationEnabledProperty); }
|
||||
set { SetValue(IsAnimationEnabledProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty HasSystemPaddingProperty = BindableProperty.Create(nameof(HasSystemPadding), typeof(bool), typeof(PopupPage), true);
|
||||
|
||||
public bool HasSystemPadding
|
||||
{
|
||||
get { return (bool)GetValue(HasSystemPaddingProperty); }
|
||||
set { SetValue(HasSystemPaddingProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty AnimationProperty = BindableProperty.Create(nameof(Animation), typeof(IPopupAnimation), typeof(PopupPage), new ScaleAnimation());
|
||||
|
||||
public IPopupAnimation Animation
|
||||
{
|
||||
get { return (IPopupAnimation)GetValue(AnimationProperty); }
|
||||
set { SetValue(AnimationProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty SystemPaddingProperty = BindableProperty.Create(nameof(SystemPadding), typeof(Thickness), typeof(PopupPage), default(Thickness), BindingMode.OneWayToSource);
|
||||
|
||||
public Thickness SystemPadding
|
||||
{
|
||||
get { return (Thickness)GetValue(SystemPaddingProperty); }
|
||||
internal set { SetValue(SystemPaddingProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty SystemPaddingSidesProperty = BindableProperty.Create(nameof(SystemPaddingSides), typeof(PaddingSide), typeof(PopupPage), PaddingSide.All);
|
||||
|
||||
public PaddingSide SystemPaddingSides
|
||||
{
|
||||
get { return (PaddingSide)GetValue(SystemPaddingSidesProperty); }
|
||||
set { SetValue(SystemPaddingSidesProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public bool CloseWhenBackgroundIsClicked
|
||||
{
|
||||
get { return (bool)GetValue(CloseWhenBackgroundIsClickedProperty); }
|
||||
@@ -39,6 +87,30 @@ public partial class PopupPage : ContentPage
|
||||
private set { SetValue(KeyboardOffsetProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly BindableProperty BackgroundClickedCommandProperty = BindableProperty.Create(nameof(BackgroundClickedCommand), typeof(ICommand), typeof(PopupPage));
|
||||
|
||||
public ICommand BackgroundClickedCommand
|
||||
{
|
||||
get => (ICommand)GetValue(BackgroundClickedCommandProperty);
|
||||
set => SetValue(BackgroundClickedCommandProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty BackgroundClickedCommandParameterProperty = BindableProperty.Create(nameof(BackgroundClickedCommandParameter), typeof(object), typeof(PopupPage));
|
||||
|
||||
public object BackgroundClickedCommandParameter
|
||||
{
|
||||
get => GetValue(BackgroundClickedCommandParameterProperty);
|
||||
set => SetValue(BackgroundClickedCommandParameterProperty, value);
|
||||
}
|
||||
|
||||
public static readonly BindableProperty AndroidTalkbackAccessibilityWorkaroundProperty = BindableProperty.Create(nameof(AndroidTalkbackAccessibilityWorkaround), typeof(bool), typeof(PopupPage), false);
|
||||
|
||||
public bool AndroidTalkbackAccessibilityWorkaround
|
||||
{
|
||||
get => (bool)GetValue(AndroidTalkbackAccessibilityWorkaroundProperty);
|
||||
set => SetValue(AndroidTalkbackAccessibilityWorkaroundProperty, value);
|
||||
}
|
||||
|
||||
public PopupPage()
|
||||
{
|
||||
BackgroundColor = Color.FromArgb("#80000000");
|
||||
@@ -48,13 +120,145 @@ public partial class PopupPage : ContentPage
|
||||
{
|
||||
return false;
|
||||
}
|
||||
protected override void OnPropertyChanged(string? propertyName = null)
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
|
||||
switch (propertyName)
|
||||
{
|
||||
case nameof(HasSystemPadding):
|
||||
case nameof(HasKeyboardOffset):
|
||||
case nameof(SystemPaddingSides):
|
||||
case nameof(SystemPadding):
|
||||
ForceLayout();
|
||||
break;
|
||||
//case nameof(IsAnimating):
|
||||
// IsAnimationEnabled = IsAnimating;
|
||||
// break;
|
||||
//case nameof(IsAnimationEnabled):
|
||||
// IsAnimating = IsAnimationEnabled;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LayoutChildren(double x, double y, double width, double height)
|
||||
{
|
||||
height -= KeyboardOffset;
|
||||
if (HasSystemPadding)
|
||||
{
|
||||
var systemPadding = SystemPadding;
|
||||
var systemPaddingSide = SystemPaddingSides;
|
||||
var left = 0d;
|
||||
var top = 0d;
|
||||
var right = 0d;
|
||||
var bottom = 0d;
|
||||
|
||||
if (systemPaddingSide.HasFlag(PaddingSide.Left))
|
||||
left = systemPadding.Left;
|
||||
if (systemPaddingSide.HasFlag(PaddingSide.Top))
|
||||
top = systemPadding.Top;
|
||||
if (systemPaddingSide.HasFlag(PaddingSide.Right))
|
||||
right = systemPadding.Right;
|
||||
if (systemPaddingSide.HasFlag(PaddingSide.Bottom))
|
||||
bottom = systemPadding.Bottom;
|
||||
|
||||
x += left;
|
||||
y += top;
|
||||
width -= left + right;
|
||||
|
||||
if (HasKeyboardOffset)
|
||||
height -= top + Math.Max(bottom, KeyboardOffset);
|
||||
else
|
||||
height -= top + bottom;
|
||||
}
|
||||
else if (HasKeyboardOffset)
|
||||
{
|
||||
height -= KeyboardOffset;
|
||||
}
|
||||
base.LayoutChildren(x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
#region Animation Methods
|
||||
|
||||
internal void PreparingAnimation()
|
||||
{
|
||||
if (IsAnimationEnabled)
|
||||
Animation?.Preparing(Content, this);
|
||||
}
|
||||
|
||||
internal void DisposingAnimation()
|
||||
{
|
||||
if (IsAnimationEnabled)
|
||||
Animation?.Disposing(Content, this);
|
||||
}
|
||||
|
||||
internal async Task AppearingAnimation()
|
||||
{
|
||||
OnAppearingAnimationBegin();
|
||||
await OnAppearingAnimationBeginAsync();
|
||||
|
||||
if (IsAnimationEnabled && Animation != null)
|
||||
await Animation.Appearing(Content, this);
|
||||
|
||||
OnAppearingAnimationEnd();
|
||||
await OnAppearingAnimationEndAsync();
|
||||
}
|
||||
|
||||
internal async Task DisappearingAnimation()
|
||||
{
|
||||
OnDisappearingAnimationBegin();
|
||||
await OnDisappearingAnimationBeginAsync();
|
||||
|
||||
if (IsAnimationEnabled && Animation != null)
|
||||
await Animation.Disappearing(Content, this);
|
||||
|
||||
OnDisappearingAnimationEnd();
|
||||
await OnDisappearingAnimationEndAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Override Animation Methods
|
||||
|
||||
protected virtual void OnAppearingAnimationBegin()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnAppearingAnimationEnd()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnDisappearingAnimationBegin()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnDisappearingAnimationEnd()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual Task OnAppearingAnimationBeginAsync()
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
protected virtual Task OnAppearingAnimationEndAsync()
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
protected virtual Task OnDisappearingAnimationBeginAsync()
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
protected virtual Task OnDisappearingAnimationEndAsync()
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual bool OnBackgroundClicked()
|
||||
{
|
||||
return CloseWhenBackgroundIsClicked;
|
||||
@@ -63,6 +267,10 @@ public partial class PopupPage : ContentPage
|
||||
internal void SendBackgroundClick()
|
||||
{
|
||||
BackgroundClicked?.Invoke(this, EventArgs.Empty);
|
||||
if (BackgroundClickedCommand?.CanExecute(BackgroundClickedCommandParameter) == true)
|
||||
{
|
||||
BackgroundClickedCommand.Execute(BackgroundClickedCommandParameter);
|
||||
}
|
||||
if (OnBackgroundClicked())
|
||||
{
|
||||
MopupService.Instance.RemovePageAsync(this).SafeFireAndForget();
|
||||
|
||||
@@ -10,9 +10,9 @@ internal static class PlatformExtension
|
||||
{
|
||||
return bindable.Handler ??= new PopupPageHandler();
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Android.Content;
|
||||
using Android.Graphics;
|
||||
using Android.Views;
|
||||
|
||||
|
||||
using Microsoft.Maui.Platform;
|
||||
|
||||
using AndroidGraphics = Android.Graphics; //Weird conflict with Microsoft namespace?
|
||||
using AndroidView = Android.Views;
|
||||
|
||||
using Mopups.Droid.Gestures;
|
||||
using Mopups.Pages;
|
||||
using Android.OS;
|
||||
using Rect = Microsoft.Maui.Graphics.Rect;
|
||||
|
||||
namespace Mopups.Platforms.Android.Renderers;
|
||||
public class PopupContentViewGroup : ContentViewGroup
|
||||
{
|
||||
public PopupPageHandler PopupHandler;
|
||||
|
||||
private readonly MopupGestureDetectorListener _gestureDetectorListener;
|
||||
private readonly GestureDetector _gestureDetector;
|
||||
private DateTime _downTime;
|
||||
private Microsoft.Maui.Graphics.Point _downPosition;
|
||||
private bool _disposed;
|
||||
public PopupContentViewGroup(Context context) : base(context)
|
||||
{
|
||||
_gestureDetectorListener = new MopupGestureDetectorListener();
|
||||
_gestureDetectorListener.Clicked += OnBackgroundClick;
|
||||
|
||||
_gestureDetector = new GestureDetector(Context, _gestureDetectorListener);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
_gestureDetectorListener.Clicked -= OnBackgroundClick;
|
||||
_gestureDetectorListener.Dispose();
|
||||
_gestureDetector.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = Platform.CurrentActivity;
|
||||
var decoreView = activity?.Window?.DecorView;
|
||||
|
||||
Thickness systemPadding;
|
||||
var keyboardOffset = 0d;
|
||||
|
||||
|
||||
var visibleRect = new AndroidGraphics.Rect();
|
||||
|
||||
decoreView?.GetWindowVisibleDisplayFrame(visibleRect);
|
||||
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.M && RootWindowInsets != null)
|
||||
{
|
||||
var h = bottom - top;
|
||||
|
||||
var windowInsets = RootWindowInsets;
|
||||
var bottomPadding = Math.Min(windowInsets.StableInsetBottom, windowInsets.SystemWindowInsetBottom);
|
||||
|
||||
if (h - visibleRect.Bottom > windowInsets.StableInsetBottom)
|
||||
{
|
||||
keyboardOffset = Context.FromPixels(h - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Thickness
|
||||
{
|
||||
Left = Context.FromPixels(windowInsets.SystemWindowInsetLeft),
|
||||
Top = Context.FromPixels(windowInsets.SystemWindowInsetTop),
|
||||
Right = Context.FromPixels(windowInsets.SystemWindowInsetRight),
|
||||
Bottom = Context.FromPixels(bottomPadding)
|
||||
};
|
||||
}
|
||||
else if (Build.VERSION.SdkInt < BuildVersionCodes.M && decoreView != null)
|
||||
{
|
||||
var screenSize = new AndroidGraphics.Point();
|
||||
activity?.WindowManager?.DefaultDisplay?.GetSize(screenSize);
|
||||
|
||||
var keyboardHeight = 0d;
|
||||
|
||||
var decoreHeight = decoreView.Height;
|
||||
var decoreWidht = decoreView.Width;
|
||||
|
||||
if (visibleRect.Bottom < screenSize.Y)
|
||||
{
|
||||
keyboardHeight = screenSize.Y - visibleRect.Bottom;
|
||||
keyboardOffset = Context.FromPixels(decoreHeight - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Thickness
|
||||
{
|
||||
Left = Context.FromPixels(visibleRect.Left),
|
||||
Top = Context.FromPixels(visibleRect.Top),
|
||||
Right = Context.FromPixels(decoreWidht - visibleRect.Right),
|
||||
Bottom = Context.FromPixels(decoreHeight - visibleRect.Bottom - keyboardHeight)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
systemPadding = new Thickness();
|
||||
}
|
||||
|
||||
(PopupHandler.VirtualView as PopupPage).SetValue(PopupPage.SystemPaddingProperty, systemPadding);
|
||||
(PopupHandler.VirtualView as PopupPage).SetValue(PopupPage.KeyboardOffsetProperty, keyboardOffset);
|
||||
|
||||
if (changed)
|
||||
(PopupHandler.VirtualView as PopupPage).Layout(new Rect(Context.FromPixels(left), Context.FromPixels(top), Context.FromPixels(right), Context.FromPixels(bottom)));
|
||||
else
|
||||
(PopupHandler.VirtualView as PopupPage).ForceLayout();
|
||||
base.OnLayout(changed, left, top, right, bottom);
|
||||
//base.OnLayout(changed, 20, 500, 1080, 2000);
|
||||
//base.OnLayout(changed, visibleRect.Left, visibleRect.Top, visibleRect.Right, visibleRect.Bottom);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void OnAttachedToWindow()
|
||||
{
|
||||
var activity = Platform.CurrentActivity;
|
||||
var decoreView = activity?.Window?.DecorView;
|
||||
//activity?.Window?.SetSoftInputMode(SoftInput.AdjustResize);
|
||||
Context.HideKeyboard(decoreView);
|
||||
base.OnAttachedToWindow();
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromWindow()
|
||||
{
|
||||
Device.StartTimer(TimeSpan.FromMilliseconds(0), () =>
|
||||
{
|
||||
var activity = Platform.CurrentActivity;
|
||||
var decoreView = activity?.Window?.DecorView;
|
||||
Context.HideKeyboard(decoreView);
|
||||
return false;
|
||||
});
|
||||
base.OnDetachedFromWindow();
|
||||
}
|
||||
|
||||
protected override void OnWindowVisibilityChanged(ViewStates visibility)
|
||||
{
|
||||
base.OnWindowVisibilityChanged(visibility);
|
||||
|
||||
// It is needed because a size of popup has not updated on Android 7+. See #209
|
||||
if (visibility == ViewStates.Visible)
|
||||
RequestLayout();
|
||||
}
|
||||
|
||||
|
||||
public override bool DispatchTouchEvent(MotionEvent e)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((PopupHandler.VirtualView as PopupPage).BackgroundInputTransparent)
|
||||
{
|
||||
return base.DispatchTouchEvent(e);
|
||||
}
|
||||
base.DispatchTouchEvent(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool OnTouchEvent(MotionEvent e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_disposed)
|
||||
return false;
|
||||
|
||||
var baseValue = base.OnTouchEvent(e);
|
||||
|
||||
_gestureDetector.OnTouchEvent(e);
|
||||
|
||||
if ((PopupHandler?.VirtualView as PopupPage).BackgroundInputTransparent)
|
||||
{
|
||||
if ((ChildCount > 0 && !IsInRegion(e.RawX, e.RawY, PopupHandler?.PlatformView.GetChildAt(0)!)) || ChildCount == 0)
|
||||
{
|
||||
(PopupHandler?.VirtualView as PopupPage).SendBackgroundClick();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return baseValue;
|
||||
}
|
||||
catch (Exception f)
|
||||
{
|
||||
|
||||
}
|
||||
return base.OnTouchEvent(e);
|
||||
}
|
||||
|
||||
private bool IsInRegion(float x, float y, AndroidView.View v)
|
||||
{
|
||||
var mCoordBuffer = new int[2];
|
||||
|
||||
v.GetLocationOnScreen(mCoordBuffer);
|
||||
return mCoordBuffer[0] + v.Width > x && // right edge
|
||||
mCoordBuffer[1] + v.Height > y && // bottom edge
|
||||
mCoordBuffer[0] < x && // left edge
|
||||
mCoordBuffer[1] < y; // top edge
|
||||
}
|
||||
|
||||
private async void OnBackgroundClick(object sender, MotionEvent e)
|
||||
{
|
||||
if (ChildCount == 0)
|
||||
return;
|
||||
|
||||
var isInRegion = IsInRegion(e.RawX, e.RawY, PopupHandler.PlatformView.GetChildAt(0));
|
||||
|
||||
if (!isInRegion)
|
||||
{
|
||||
(PopupHandler.VirtualView as PopupPage).SendBackgroundClick();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,218 +4,42 @@ using Android.Views;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
using Mopups.Droid.Gestures;
|
||||
using Mopups.Platforms.Android.Renderers;
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace Mopups.Pages;
|
||||
|
||||
public class PopupPageHandler : ContentViewHandler
|
||||
public class PopupPageHandler : PageHandler
|
||||
{
|
||||
private readonly MopupGestureDetectorListener _gestureDetectorListener;
|
||||
private readonly GestureDetector _gestureDetector;
|
||||
private DateTime _downTime;
|
||||
private Microsoft.Maui.Graphics.Point _downPosition;
|
||||
private bool _disposed;
|
||||
public bool _disposed;
|
||||
|
||||
public PopupPageHandler()
|
||||
{
|
||||
try
|
||||
{
|
||||
//--HACK--
|
||||
this.SetMauiContext(new MauiContext(MauiApplication.Current.Services, MauiApplication.Current.ApplicationContext));
|
||||
//
|
||||
_gestureDetectorListener = new MopupGestureDetectorListener();
|
||||
|
||||
_gestureDetectorListener.Clicked += OnBackgroundClick;
|
||||
this.SetMauiContext(MauiApplication.Current.Application.Windows[0].Handler.MauiContext);
|
||||
|
||||
_gestureDetector = new GestureDetector(MauiApplication.Current.ApplicationContext, _gestureDetectorListener);
|
||||
ForceHandlerPauseWaitForVirtualView();
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
//--HACK--
|
||||
void ForceHandlerPauseWaitForVirtualView()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (this.VirtualView == null)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
this.PlatformView.LayoutChange += PopupPage_LayoutChange;
|
||||
this.PlatformView.Touch += NativeView_Touch;
|
||||
this.PlatformView.Touch += NativeView_Touch1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void NativeView_Touch1(object? sender, Android.Views.View.TouchEventArgs e)
|
||||
protected override void ConnectHandler(ContentViewGroup platformView)
|
||||
{
|
||||
OnTouchEvent(sender, e.Event);
|
||||
|
||||
(platformView as PopupContentViewGroup).PopupHandler = this;
|
||||
base.ConnectHandler(platformView);
|
||||
}
|
||||
|
||||
protected override ContentViewGroup CreatePlatformView()
|
||||
{
|
||||
var item = new PopupContentViewGroup(Context);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
private bool OnTouchEvent(object? sender, MotionEvent? e)
|
||||
protected override void DisconnectHandler(ContentViewGroup platformView)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//platformView.Dispose();
|
||||
base.DisconnectHandler(platformView);
|
||||
|
||||
var baseValue = (sender as Android.Views.View).OnTouchEvent(e);
|
||||
|
||||
_gestureDetector.OnTouchEvent(e);
|
||||
|
||||
if ((sender as PopupPage)?.BackgroundInputTransparent == true)
|
||||
{
|
||||
OnBackgroundClick(sender, e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnBackgroundClick(object? sender, MotionEvent e)
|
||||
{
|
||||
var isInRegion = IsInRegion(e.RawX, e.RawY, (sender as Android.Views.View)!);
|
||||
|
||||
if (!isInRegion)
|
||||
(sender as PopupPage).SendBackgroundClick();
|
||||
}
|
||||
|
||||
// Fix for "CloseWhenBackgroundIsClicked not works on Android with Xamarin.Forms 2.4.0.280" #173
|
||||
private bool IsInRegion(float x, float y, Android.Views.View v)
|
||||
{
|
||||
var mCoordBuffer = new int[2];
|
||||
|
||||
v.GetLocationOnScreen(mCoordBuffer);
|
||||
return mCoordBuffer[0] + v.Width > x && // right edge
|
||||
mCoordBuffer[1] + v.Height > y && // bottom edge
|
||||
mCoordBuffer[0] < x && // left edge
|
||||
mCoordBuffer[1] < y; // top edge
|
||||
}
|
||||
|
||||
private void NativeView_Touch(object? sender, Android.Views.View.TouchEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
DispatchTouchEvent(e.Event);
|
||||
|
||||
void DispatchTouchEvent(MotionEvent e)
|
||||
{
|
||||
|
||||
if (e.Action == MotionEventActions.Down)
|
||||
{
|
||||
_downTime = DateTime.UtcNow;
|
||||
_downPosition = new Microsoft.Maui.Graphics.Point(e.RawX, e.RawY);
|
||||
}
|
||||
if (e.Action != MotionEventActions.Up)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
Android.Views.View? currentFocus1 = Platform.CurrentActivity.CurrentFocus;
|
||||
|
||||
if (currentFocus1 is Android.Widget.EditText)
|
||||
{
|
||||
Android.Views.View? currentFocus2 = Platform.CurrentActivity.CurrentFocus;
|
||||
if (currentFocus1 == currentFocus2 && _downPosition.Distance(new(e.RawX, e.RawY)) <= Context.ToPixels(20.0) && !(DateTime.UtcNow - _downTime > TimeSpan.FromMilliseconds(200.0)))
|
||||
{
|
||||
int[] location = new int[2];
|
||||
currentFocus1.GetLocationOnScreen(location);
|
||||
float num1 = e.RawX + currentFocus1.Left - location[0];
|
||||
float num2 = e.RawY + currentFocus1.Top - location[1];
|
||||
if (!new Rectangle(currentFocus1.Left, currentFocus1.Top, currentFocus1.Width, currentFocus1.Height).Contains((int)num1, (int)num2))
|
||||
{
|
||||
Context.HideKeyboard(currentFocus1);
|
||||
currentFocus1.ClearFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopupPage_LayoutChange(object? sender, Android.Views.View.LayoutChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = Platform.CurrentActivity;
|
||||
|
||||
Thickness systemPadding;
|
||||
var keyboardOffset = 0d;
|
||||
|
||||
var decoreView = activity.Window.DecorView;
|
||||
var decoreHeight = decoreView.Height;
|
||||
var decoreWidth = decoreView.Width;
|
||||
|
||||
using var visibleRect = new Android.Graphics.Rect();
|
||||
|
||||
decoreView?.GetWindowVisibleDisplayFrame(visibleRect);
|
||||
|
||||
using var screenSize = new Android.Graphics.Point();
|
||||
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
|
||||
{
|
||||
|
||||
var windowInsets = activity?.WindowManager?.DefaultDisplay?.Cutout;
|
||||
|
||||
|
||||
var bottomPadding = windowInsets?.SafeInsetBottom;
|
||||
|
||||
if (screenSize.Y - visibleRect.Bottom > bottomPadding)
|
||||
{
|
||||
keyboardOffset = Context.FromPixels(screenSize.Y - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Microsoft.Maui.Thickness
|
||||
{
|
||||
Left = Context.FromPixels(windowInsets.SafeInsetLeft),
|
||||
Top = Context.FromPixels(windowInsets.SafeInsetTop),
|
||||
Right = Context.FromPixels(windowInsets.SafeInsetRight),
|
||||
Bottom = Context.FromPixels(bottomPadding.Value)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var keyboardHeight = 0d;
|
||||
|
||||
if (visibleRect.Bottom < screenSize.Y)
|
||||
{
|
||||
keyboardHeight = screenSize.Y - visibleRect.Bottom;
|
||||
keyboardOffset = Context.FromPixels(decoreHeight - visibleRect.Bottom);
|
||||
}
|
||||
|
||||
systemPadding = new Microsoft.Maui.Thickness
|
||||
{
|
||||
Left = Context.FromPixels(visibleRect.Left),
|
||||
Top = Context.FromPixels(visibleRect.Top),
|
||||
Right = Context.FromPixels(decoreWidth - visibleRect.Right),
|
||||
Bottom = Context.FromPixels(decoreHeight - visibleRect.Bottom - keyboardHeight)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//CurrentElement.SetValue(PopupPage.SystemPaddingProperty, systemPadding);
|
||||
//CurrentElement.SetValue(PopupPage.KeyboardOffsetProperty, keyboardOffset);
|
||||
this.PlatformView.Layout((int)Context.FromPixels(e.Left), (int)Context.FromPixels(e.Top), (int)Context.FromPixels(e.Right), (int)Context.FromPixels(e.Bottom));
|
||||
this.PlatformView.ForceLayout();
|
||||
|
||||
//base.OnLayout(changed, l, t, r, b);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
"profiles": {
|
||||
"Mopups": {
|
||||
"commandName": "Project",
|
||||
"hotReloadEnabled": false,
|
||||
"nativeDebugging": true
|
||||
"hotReloadEnabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using Mopups.Pages;
|
||||
using Mopups.Services;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using ScrollView = Microsoft.Maui.Controls.ScrollView;
|
||||
|
||||
namespace SampleMaui.CSharpMarkup;
|
||||
|
||||
@@ -23,13 +22,7 @@ public partial class LoginPage : PopupPage
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Content = new ScrollView
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
BackgroundColor = Color.FromRgb(200.00, 0.00, 0.00),
|
||||
Content = GenerateLoginView()
|
||||
};
|
||||
this.Content = GenerateLoginView();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -58,27 +51,15 @@ public partial class LoginPage : PopupPage
|
||||
[MemberNotNull(nameof(UsernameEntry))]
|
||||
[MemberNotNull(nameof(PasswordEntry))]
|
||||
[MemberNotNull(nameof(LoginButton))]
|
||||
private StackLayout GenerateFrameContainerContent()
|
||||
private VerticalStackLayout GenerateFrameContainerContent()
|
||||
{
|
||||
var frameContainerContent = new StackLayout
|
||||
|
||||
var frameContainerContent = new VerticalStackLayout
|
||||
{
|
||||
|
||||
Margin = new Thickness(1),
|
||||
Padding = new Thickness(1, 1),
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
};
|
||||
/*
|
||||
DotNetBotImage = new Image
|
||||
{
|
||||
|
||||
Margin = new Microsoft.Maui.Thickness(1),
|
||||
BackgroundColor = Microsoft.Maui.Graphics.Colors.White,
|
||||
Scale = 10,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Source = ImageSource.FromFile("fluent_balloon.svg")
|
||||
};
|
||||
*/
|
||||
UsernameEntry = new Entry
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
@@ -95,17 +76,25 @@ public partial class LoginPage : PopupPage
|
||||
PlaceholderColor = Color.FromArgb("#FF9CDAF1"),
|
||||
TextColor = Color.FromArgb("#FF7DBBE6")
|
||||
};
|
||||
|
||||
/*
|
||||
LoginButton = new Button
|
||||
{
|
||||
Command = new Command(() => MopupService.Instance.PopAllAsync())
|
||||
};
|
||||
|
||||
*/
|
||||
//frameContainerContent.Add(DotNetBotImage);
|
||||
frameContainerContent.Add(UsernameEntry);
|
||||
frameContainerContent.Add(PasswordEntry);
|
||||
frameContainerContent.Add(LoginButton);
|
||||
|
||||
//frameContainerContent.Add(LoginButton);
|
||||
return frameContainerContent;
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
MopupService.Instance.PopAllAsync();
|
||||
return base.OnBackButtonPressed();
|
||||
}).Result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace SampleMaui.CSharpMarkup;
|
||||
|
||||
public partial class MainPage : ContentPage
|
||||
{
|
||||
[Obsolete]
|
||||
protected void BuildContent()
|
||||
{
|
||||
BackgroundColor = Color.FromRgb(255, 255, 255);
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
|
||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:theme="@style/AppTheme"></application>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
</manifest>
|
||||
@@ -9,7 +9,7 @@ public class MainApplication : MauiApplication
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
|
||||
: base(handle, ownership)
|
||||
{
|
||||
Microsoft.Maui.Essentials.Platform.Init(Current);
|
||||
Microsoft.Maui.ApplicationModel.Platform.Init(Current);
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp()
|
||||
|
||||
6
SampleMaui/Platforms/Android/Resources/values/style.xml
Normal file
6
SampleMaui/Platforms/Android/Resources/values/style.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<resources>
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
|
||||
<!-- Customize your theme -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -2,8 +2,7 @@
|
||||
"profiles": {
|
||||
"SampleMopups": {
|
||||
"commandName": "Project",
|
||||
"hotReloadEnabled": false,
|
||||
"nativeDebugging": true
|
||||
"hotReloadEnabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK.InteractiveExperiences" Version="1.0.0-experimental1" NoWarn="NU1701" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AsyncAwaitBestPractices.MVVM" Version="6.0.4" />
|
||||
</ItemGroup>
|
||||
@@ -87,11 +88,14 @@
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0-android|AnyCPU'">
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
<Optimize>True</Optimize>
|
||||
<Optimize>False</Optimize>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net6.0-android|AnyCPU'">
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
<Optimize>False</Optimize>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user