前言
关于MAUI Blazor Android 输入框软键盘遮挡问题,之前的文章已经有了答案,MAUI Blazor Android 输入框软键盘遮挡问题
但是这个方案一直存在一点小的瑕疵
在小窗模式下,界面的高度始终不正确
所以本篇文章重点解决这个问题
特别感谢这篇文章 Android webView输入框软键盘遮挡问题-终极解决方案(不好使你打我) ,上一篇文章忘记感谢了,非常抱歉。
1. 之前方案的整理
之前文章的代码有些乱,小大写以及空值判断都没有处理,强迫症表示很难受。
所以讨论新问题之前,先把之前的代码整理一遍。
using Android.Content.Res;
using Android.Widget;
using System.Runtime.Versioning;
using static Android.Resource;
using Activity = Android.App.Activity;
using Rect = Android.Graphics.Rect;
using View = Android.Views.View;
namespace MauiBlazor3.Platform;
[SupportedOSPlatform("Android")]
public static partial 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);
if (MChildOfContent?.ViewTreeObserver == null) return;
MChildOfContent.ViewTreeObserver.GlobalLayout += (s, o) => PossiblyResizeChildOfContent();
FrameLayoutParams = (FrameLayout.LayoutParams?)MChildOfContent?.LayoutParameters;
}
static void PossiblyResizeChildOfContent()
{
if (MChildOfContent?.RootView == null) return;
if (FrameLayoutParams == null) return;
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 - rect.Top;
}
}
Platforms/Android/MainActivity.cs中添加以下代码
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
WebViewSoftInputPatch.Initialize();
}
2. 小窗模式界面高度不正确
问题展示
可以很清楚的看到,小窗模式下,下面那一部分被吃掉了。这个是无法滚动的。
也就是说,界面渲染的高度实际上是大于小窗屏幕的高度。
那一部分哪去了,经过简单的调试,发现恰恰就是状态栏的高度
也就是代码中的这一部分
static int ComputeUsableHeight()
{
Rect rect = new Rect();
MChildOfContent?.GetWindowVisibleDisplayFrame(rect);
return rect.Bottom - rect.Top;
}
小窗模式时,rect.Top
返回的永远是0,而不是状态栏高度
解决办法
我们重新写一个获取状态栏高度的方法,用它去替代rect.Top
static int ComputeUsableHeight()
{
Rect rect = new Rect();
MChildOfContent?.GetWindowVisibleDisplayFrame(rect);
return rect.Bottom - GetStatusBarHeight();
}
static int GetStatusBarHeight()
{
int result = 0;
Resources resources = Activity.Resources ?? throw new InvalidOperationException("Activity Resources can't be null.");
int resourceId = resources.GetIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
{
result = resources.GetDimensionPixelSize(resourceId);
}
return result;
}
标签:int,Rect,输入框,软键盘,static,MChildOfContent,MAUI,Android,rect
From: https://www.cnblogs.com/Yu-Core/p/17525807.html