diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs index e982d4831e25..377844705a68 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs @@ -265,21 +265,9 @@ void UpdateStatusBarColor(ShellAppearance appearance) var activity = AndroidContext.GetActivity(); var window = activity?.Window; var decorView = window?.DecorView; - var resources = AndroidContext.Resources; - int statusBarHeight = 0; - int resourceId = resources.GetIdentifier("status_bar_height", "dimen", "android"); - if (resourceId > 0) - { - statusBarHeight = resources.GetDimensionPixelSize(resourceId); - } - - int navigationBarHeight = 0; - resourceId = resources.GetIdentifier("navigation_bar_height", "dimen", "android"); - if (resourceId > 0) - { - navigationBarHeight = resources.GetDimensionPixelSize(resourceId); - } + int statusBarHeight = AndroidContext.GetStatusBarHeight(); + int navigationBarHeight = AndroidContext.GetNavigationBarHeight(); // we are using the split drawable here to avoid GPU overdraw. // All it really is is a drawable that only draws under the statusbar/bottom bar to make sure diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index 2eb93b3e7fb8..3b7b0bc514ed 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -20,7 +20,7 @@ ViewGroup GetModalParentView() { var currentRootView = GetCurrentRootView() as ViewGroup; - if(_window?.PlatformActivity?.GetWindow() == _window) + if (_window?.PlatformActivity?.GetWindow() == _window) { currentRootView = _window?.PlatformActivity?.Window?.DecorView as ViewGroup; } @@ -227,6 +227,12 @@ public ModalContainer( .Commit(); } + public override bool OnTouchEvent(MotionEvent? e) + { + // Don't let touch events pass through to the view being covered up + return true; + } + protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (Context == null || NavigationRootManager?.RootView == null) @@ -240,23 +246,24 @@ protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) if (widthMeasureSpec.GetMode() == MeasureSpecMode.AtMost) widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(widthMeasureSpec.GetSize()); - if (heightMeasureSpec.GetMode() == MeasureSpecMode.AtMost) - heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(heightMeasureSpec.GetSize()); + var measureHeight = heightMeasureSpec.GetSize() - Context.GetNavigationBarHeight(); + heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(measureHeight); rootView.Measure(widthMeasureSpec, heightMeasureSpec); SetMeasuredDimension(rootView.MeasuredWidth, rootView.MeasuredHeight); } - protected override void OnLayout(bool changed, int l, int t, int r, int b) { if (Context == null || NavigationRootManager?.RootView == null) return; + var statusBarHeight = Context.GetStatusBarHeight(); NavigationRootManager - .RootView.Layout(l, t, r, b); + .RootView + .Layout(l, t + statusBarHeight, r, b); - _backgroundView.Layout(0, 0, r - l, b - t); + _backgroundView.Layout(0, statusBarHeight, r - l, b - t); } void OnModalPagePropertyChanged(object? sender, PropertyChangedEventArgs e) diff --git a/src/Core/src/Platform/Android/ContextExtensions.cs b/src/Core/src/Platform/Android/ContextExtensions.cs index 1cf0f7b8ee77..36d89d4460a6 100644 --- a/src/Core/src/Platform/Android/ContextExtensions.cs +++ b/src/Core/src/Platform/Android/ContextExtensions.cs @@ -27,6 +27,8 @@ public static class ContextExtensions static float s_displayDensity = float.MinValue; static int? _actionBarHeight; + static int? _statusBarHeight; + static int? _navigationBarHeight; // TODO FromPixels/ToPixels is both not terribly descriptive and also possibly sort of inaccurate? // These need better names. It's really To/From Device-Independent, but that doesn't exactly roll off the tongue. @@ -295,13 +297,50 @@ internal static Color GetAccentColor(this Context context) return rc ?? Color.FromArgb("#ff33b5e5"); } - public static int GetActionBarHeight(this Context context) { _actionBarHeight ??= (int)context.GetThemeAttributePixels(Resource.Attribute.actionBarSize); return _actionBarHeight.Value; } + internal static int GetStatusBarHeight(this Context context) + { + if (_statusBarHeight != null) + return _statusBarHeight.Value; + + var resources = context.Resources; + + if (resources == null) + return 0; + + int resourceId = resources.GetIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) + { + _statusBarHeight = resources.GetDimensionPixelSize(resourceId); + } + + return _statusBarHeight ?? 0; + } + + internal static int GetNavigationBarHeight(this Context context) + { + if (_navigationBarHeight != null) + return _navigationBarHeight.Value; + + var resources = context.Resources; + + if (resources == null) + return 0; + + int resourceId = resources.GetIdentifier("navigation_bar_height", "dimen", "android"); + if (resourceId > 0) + { + _navigationBarHeight = resources.GetDimensionPixelSize(resourceId); + } + + return _navigationBarHeight ?? 0; + } + internal static int CreateMeasureSpec(this Context context, double constraint, double explicitSize, double maximumSize) { var mode = MeasureSpecMode.AtMost;