前言

关于MAUI Blazor Android 输入框软键盘遮挡问题,之前的文章已经有了答案,MAUI Blazor Android 输入框软键盘遮挡问题

但是这个方案一直存在一点小的瑕疵

在小窗模式下,界面的高度始终不正确

所以本篇文章重点解决这个问题

特别感谢这篇文章 Android webView输入框软键盘遮挡问题-终极解决方案(不好使你打我) ,上一篇文章忘记感谢了,非常抱歉。

1. 小窗模式界面高度不正确

问题展示


可以很清楚的看到,小窗模式下,下面那一部分被吃掉了。这个是无法滚动的。

也就是说,界面渲染的高度实际上是大于小窗屏幕的高度。

那一部分哪去了,经过简单的调试,发现恰恰就是状态栏的高度

也就是代码中的这一部分

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;
}

2. 全屏模式

然而又出现了新的问题,如果取消状态栏,那么界面高度又不正确了

很快找到解决办法

static int ComputeUsableHeight()
{
Rect rect = new Rect();
MChildOfContent.GetWindowVisibleDisplayFrame(rect);
if (IsImmersiveMode())
{
return rect.Bottom;
}
else
{
return rect.Bottom - GetStatusBarHeight();
}
} static bool IsImmersiveMode()
{
View decorView = Activity.Window.DecorView;
int uiOptions = (int)decorView.SystemUiVisibility;
return (uiOptions & (int)SystemUiFlags.Immersive) == (int)SystemUiFlags.Immersive;
}

4. 最终全部代码

Platform/Android/WebViewSoftInputPatch.cs

using Android.Content.Res;
using Android.Views;
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.Android; [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);
if (IsImmersiveMode())
{
return rect.Bottom;
}
else
{
return rect.Bottom - GetStatusBarHeight();
}
} static int GetStatusBarHeight()
{
int result = 0;
Resources resources = Activity.Resources;
int resourceId = resources.GetIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
{
result = resources.GetDimensionPixelSize(resourceId);
}
return result;
} static bool IsImmersiveMode()
{
View decorView = Activity.Window.DecorView;
int uiOptions = (int)decorView.SystemUiVisibility;
return (uiOptions & (int)SystemUiFlags.Immersive) == (int)SystemUiFlags.Immersive;
}
}

Platform/Android/MainActivity.cs

protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
WebViewSoftInputPatch.Initialize();
}

MAUI Blazor Android 输入框软键盘遮挡问题2.0的更多相关文章

  1. Android软键盘遮挡的四种解决方案

    问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入 ...

  2. Android软键盘遮挡布局的那些事

    有朋友提到软键盘遮挡布局的问题,说网上找了很多资料都未能解决,下面我来总结一下那些事,有些内容也是从网友那里学来的,但是我都会自己验证正确了才会贴出来. 首先来分析下我们常见的遮挡问题有哪些(本次所说 ...

  3. Android软键盘遮挡布局问题;

    布局被软键盘遮挡虽然不是什么大问题,但还是比较影响用户体验的:最让人恼火的是当前输入框被软键盘被遮挡,来看一下解决方法: 1.当前输入框被软键盘遮挡,仅把输入框显示出来,不改变整体布局: 设置Mani ...

  4. 移动端页面input输入框被键盘遮挡问题

    <body class="layout-fixed"> <!-- fixed定位的头部 --> <header> </header> ...

  5. Android隐藏软键盘收回软键盘

    代码改变世界 Android隐藏软键盘收回软键盘 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPU ...

  6. ios上有时候提交按钮点击两次才可以取消输入框软键盘

    ios上有时候提交按钮点击两次才可以取消输入框软键盘,点击第一次软键盘消失,点击第二次输入框页面消失,这样用户体验不好.我的做法是用 touchstart 代替click来处理 反应快,但是有时候会出 ...

  7. Android WebView 软键盘挡住输入框

    解决方法一: 在所在的Activity中加入 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RES ...

  8. android开发 软键盘出现后 防止EditText控件遮挡 总体平移UI

    在EditText控件接近底部的情况下 软键盘弹出后会把获得焦点的EditText控件遮挡 无法看到输入信息  防止这种情况发生 就须要设置AndroidManifest.xml的属性 前面的xml信 ...

  9. 安卓H5软键盘遮挡输入框

    由于安卓app内嵌入H5页面,webview对于软键盘没有处理(如果不是产品强烈要求建议不要处理这种拆东墙补西墙的问题,因为其他的手机上可能会出现已经优化软键盘的情况) 1.input下方还有多余空位 ...

  10. ios移动输入框被软键盘遮挡

    页面输入框会出现被软键盘挡住的问题: 解决方法:获取input点击事件设置body高度 $('input').bind('click',function(e){ var $this = $(this) ...

随机推荐

  1. rails的接口查询详解

    Retrieving Objects from the Database find "find"是一种常用的数据库查询方法,在Rails中被用于从数据库中查找单个记录.它可以接收一 ...

  2. 获取电脑的网络连接状态(三)Ping

    网络连接判断,使用ping测试获取: 1 private static async Task<bool> IsPingSuccess() 2 { 3 try 4 { 5 using (Pi ...

  3. [C++提高编程] 1、模板

    文章目录 1 模板 1.1 模板的概念 1.2 函数模板 1.2.1 函数模板语法 1.2.2 函数模板注意事项 1.2.3 函数模板案例 1.2.4 普通函数与函数模板的区别 1.2.5 普通函数与 ...

  4. Prism Sample 16-RegionContext

    终于发现一个有趣的新知识了. 本例的核心是RegionContext,意思是一个区域的上下文.但与DataContext似乎并不相同. 先看一下整体思路. 在主窗体上只有一个Region: <G ...

  5. sqlilabs第一关

    首先打开网页,进行注入点的测试 输入?id=1 and 1=1发现1=2的时候没有进行报错,有两种可能,一种是不能注入,第二种是字符型可以通过对字符型里面的''进行闭合,输入'and 1=1--+发现 ...

  6. 不是单例的单例——巧用ClassLoader

    本文通过如何将一个单例类实例化两次的案例,用代码实践来引入 Java 类加载器相关的概念与工作机制.理解并熟练掌握相关知识之后可以扩宽解决问题的思路,另辟蹊径,达到目的. 背景 单例模式是最常用的设计 ...

  7. request args kwargs的作用

    self.request : 包含了请求过来的对象 self.args:请求传递过来的参数,列表形式 self.kwargs:请求传递过来的参数,字典形式

  8. ToolStrip1

    Private Sub ToolStrip1_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs) Handles Too ...

  9. java设计模式【抽象工厂模式】

    java设计模式[抽象工厂模式] 抽象工厂模式 抽象工厂模式是对简单工厂模式的一个变种,它允许通过一个统一的接口来创建不同的产品实例,而无需指定具体的子类.在这个模式中,我们只关心产品的抽象接口,而将 ...

  10. 【熊子q的代码乐园】用python写个健康报备记录小系统

    目录 一.前言 二.技术实现 1.概述 2. 环境 3. 技术核心 4. 数据库 5. 源代码 三.最后 一.前言 coding的一路上,遇到过许多问题,也写过一些代码去解决,回头看看还是有点意思的, ...