MAUI Blazor Android 输入框软键盘遮挡问题
前言
(提示!!!.Net 8已不存在该问题,按照https://learn.microsoft.com/zh-cn/dotnet/maui/android/platform-specifics/soft-keyboard-input-mode中的方法就可以了)
最近才发现MAUI Blazor Android存在输入框软键盘遮挡这个问题,搜索了一番,原来这是安卓webview一个由来已久的问题,还好有大佬提出了解决方案 AndroidBug5497Workaround,但是这是Java代码,MAUI中需要做一些小的修改,修改一些方法名还有类的明确引用。废话不多说,直接上代码。
解决方案
第一步
将下面的代码添加到Platforms/Android文件夹中,注意using ,一个也不能少,我最开始就是因为缺少using Rect = Android.Graphics.Rect;
没有成功。命名空间也别忘了更改。
using Android.App;
using Android.Content;
using Android.Content.Res;
using Android.Widget;
using static Android.Resource;
using Rect = Android.Graphics.Rect;
using View = Android.Views.View;
namespace MauiBlazor3.Platforms.Android
{
#nullable disable
public class GlobalLayoutUtil
{
private bool isImmersed = false;
private View mChildOfContent;
private FrameLayout.LayoutParams frameLayoutParams;
private int usableHeightPrevious = 0;
public static void AssistActivity(Activity activity)
{
_ = new GlobalLayoutUtil(activity);
}
public GlobalLayoutUtil(Activity activity)
{
FrameLayout content = (FrameLayout)activity.FindViewById(Id.Content);
mChildOfContent = content.GetChildAt(0);
mChildOfContent.ViewTreeObserver.GlobalLayout += (s, o) => PossiblyResizeChildOfContent(activity);
frameLayoutParams = (FrameLayout.LayoutParams)mChildOfContent.LayoutParameters;
}
private void PossiblyResizeChildOfContent(Activity activity)
{
//当前可视区域的高度
int usableHeightNow = ComputeUsableHeight();
//当前高度值和之前的进行对比,变化将进行重新绘制
if (usableHeightNow != usableHeightPrevious)
{
//获取当前屏幕高度
//Ps: 并不是真正的屏幕高度,是当前app的窗口高度,分屏时的高度为分屏窗口高度
int usableHeightSansKeyboard = mChildOfContent.RootView.Height;
// 高度差值:屏幕高度 - 可视内容高度
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
// 差值为负,说明获取屏幕高度时出错,宽高状态值反了,重新计算
if (heightDifference < 0)
{
usableHeightSansKeyboard = mChildOfContent.RootView.Width;
heightDifference = usableHeightSansKeyboard - usableHeightNow;
}
// keyboard probably just became visible
// 如果差值大于屏幕高度的 1/4,则认为输入软键盘为弹出状态
if (heightDifference > usableHeightSansKeyboard / 4)
{
// 设置布局高度为:屏幕高度 - 高度差
frameLayoutParams.Height = usableHeightSansKeyboard - heightDifference;
}
//else if (heightDifference >= GetNavigationBarHeight(activity))
//{
// // keyboard probably just became hidden
// // 虚拟导航栏显示
// frameLayoutParams.Height = usableHeightNow - GetNavigationBarHeight(activity);
//}
else
{// 其他情况直接设置为可视高度即可
frameLayoutParams.Height = usableHeightNow;
}
}
// 刷新布局,会重新测量、绘制
mChildOfContent.RequestLayout();
// 保存高度信息
usableHeightPrevious = usableHeightNow;
}
/**
* 获取可视内容区域的高度
*/
private int ComputeUsableHeight()
{
Rect rect = new Rect();
mChildOfContent.GetWindowVisibleDisplayFrame(rect);
if (isImmersed)
return (int)rect.Bottom;
else
return (int)(rect.Bottom - rect.Top);
}
/**
* 获取导航栏的真实高度
*
* @param context:
* @return: 导航栏高度
*/
private static int GetNavigationBarHeight(Context context)
{
int result = 0;
Resources resources = context.Resources;
int resourceId =
resources.GetIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0)
result = resources.GetDimensionPixelSize(resourceId);
return result;
}
}
}
第二步
Platforms/Android/MainActivity.cs中添加以下代码
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
GlobalLayoutUtil.AssistActivity(this);
}