Skip to content

Commit

Permalink
Merge pull request #188 from LiamMorrow/fix-keybaord
Browse files Browse the repository at this point in the history
  • Loading branch information
LiamMorrow authored Jul 1, 2024
2 parents ebc8e30 + d4bace0 commit 1b1bb0c
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 4 deletions.
26 changes: 22 additions & 4 deletions LiftLog.App/Platforms/Android/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,20 @@ protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
WindowCompat.SetDecorFitsSystemWindows(Window!, false);
WebViewSoftInputPatch.Initialize();
var insetsManager =
IPlatformApplication.Current?.Services.GetRequiredService<InsetsManager>();
ViewCompat.SetOnApplyWindowInsetsListener(
Window!.DecorView,
new WindowInsetsListener(insetsManager!, Resources!.DisplayMetrics!.Density)
);
if (insetsManager is not null)
{
insetsManager.SystemSafeInsetBottom =
$"{WebViewSoftInputPatch.GetNavBarHeight() / Resources!.DisplayMetrics!.Density}px";
insetsManager.SystemSafeInsetTop =
$"{WebViewSoftInputPatch.GetStatusBarHeight() / Resources.DisplayMetrics.Density}px";
ViewCompat.SetOnApplyWindowInsetsListener(
Window!.DecorView,
new WindowInsetsListener(insetsManager!, Resources.DisplayMetrics.Density)
);
}
}

private class WindowInsetsListener(InsetsManager insetsManager, float density)
Expand All @@ -59,8 +67,18 @@ WindowInsetsCompat insets
)
{
// convert android px to css px

var top = insets.SystemWindowInsetTop / density;
var bottom = insets.SystemWindowInsetBottom / density;
if (top == 0 || bottom == 0)
{
insetsManager.SystemSafeInsetBottom =
$"{WebViewSoftInputPatch.GetNavBarHeight() / density}px";
insetsManager.SystemSafeInsetTop =
$"{WebViewSoftInputPatch.GetStatusBarHeight() / density}px";
insetsManager.NotifyInsetsChanged();
return insets;
}
insetsManager.SystemSafeInsetTop = $"{top}px";
insetsManager.SystemSafeInsetBottom = $"{bottom}px";
insetsManager.NotifyInsetsChanged();
Expand Down
86 changes: 86 additions & 0 deletions LiftLog.App/Platforms/Android/WebViewSoftInputPatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System.Runtime.Versioning;
using Android.Content.Res;
using Android.Views;
using Android.Widget;
using static Android.Resource;
using Activity = Android.App.Activity;
using Rect = Android.Graphics.Rect;
using View = Android.Views.View;

namespace LiftLog.App;

[SupportedOSPlatform("Android")]
public static class WebViewSoftInputPatch
{
static Activity Activity =>
Microsoft.Maui.ApplicationModel.Platform.CurrentActivity
?? throw new InvalidOperationException("Android Activity can't be null.");
static View MChildOfContent;
static FrameLayout.LayoutParams FrameLayoutParams;
static int UsableHeightPrevious = 0;

public static void Initialize()
{
FrameLayout content = (FrameLayout)Activity.FindViewById(Id.Content);
MChildOfContent = content.GetChildAt(0);
MChildOfContent.ViewTreeObserver.GlobalLayout += (s, o) => PossiblyResizeChildOfContent();
FrameLayoutParams = (FrameLayout.LayoutParams)MChildOfContent?.LayoutParameters;
}

static void PossiblyResizeChildOfContent()
{
int usableHeightNow = ComputeUsableHeight();
if (usableHeightNow != UsableHeightPrevious)
{
int usableHeightSansKeyboard = MChildOfContent.RootView.Height;
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference < 0)
{
usableHeightSansKeyboard = MChildOfContent.RootView.Width;
heightDifference = usableHeightSansKeyboard - usableHeightNow;
}

if (heightDifference > usableHeightSansKeyboard / 4)
{
FrameLayoutParams.Height = usableHeightSansKeyboard - heightDifference;
}
else
{
FrameLayoutParams.Height = usableHeightNow;
}
}

MChildOfContent.RequestLayout();
UsableHeightPrevious = usableHeightNow;
}

static int ComputeUsableHeight()
{
Rect rect = new Rect();
MChildOfContent.GetWindowVisibleDisplayFrame(rect);
return rect.Bottom + GetNavBarHeight();
}

public static int GetNavBarHeight()
{
int result = 0;
Resources resources = Activity.Resources;
int resourceId = resources.GetIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0)
{
result = resources.GetDimensionPixelSize(resourceId);
}
return result;
}

public static int GetStatusBarHeight()
{
int result = 0;
int resourceId = Activity.Resources.GetIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
{
result = Activity.Resources.GetDimensionPixelSize(resourceId);
}
return result;
}
}

0 comments on commit 1b1bb0c

Please sign in to comment.