MAUI Blazor Android 输入框软键盘遮挡问题2.0
前言
关于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的更多相关文章
- Android软键盘遮挡的四种解决方案
问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入 ...
- Android软键盘遮挡布局的那些事
有朋友提到软键盘遮挡布局的问题,说网上找了很多资料都未能解决,下面我来总结一下那些事,有些内容也是从网友那里学来的,但是我都会自己验证正确了才会贴出来. 首先来分析下我们常见的遮挡问题有哪些(本次所说 ...
- Android软键盘遮挡布局问题;
布局被软键盘遮挡虽然不是什么大问题,但还是比较影响用户体验的:最让人恼火的是当前输入框被软键盘被遮挡,来看一下解决方法: 1.当前输入框被软键盘遮挡,仅把输入框显示出来,不改变整体布局: 设置Mani ...
- 移动端页面input输入框被键盘遮挡问题
<body class="layout-fixed"> <!-- fixed定位的头部 --> <header> </header> ...
- Android隐藏软键盘收回软键盘
代码改变世界 Android隐藏软键盘收回软键盘 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPU ...
- ios上有时候提交按钮点击两次才可以取消输入框软键盘
ios上有时候提交按钮点击两次才可以取消输入框软键盘,点击第一次软键盘消失,点击第二次输入框页面消失,这样用户体验不好.我的做法是用 touchstart 代替click来处理 反应快,但是有时候会出 ...
- Android WebView 软键盘挡住输入框
解决方法一: 在所在的Activity中加入 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RES ...
- android开发 软键盘出现后 防止EditText控件遮挡 总体平移UI
在EditText控件接近底部的情况下 软键盘弹出后会把获得焦点的EditText控件遮挡 无法看到输入信息 防止这种情况发生 就须要设置AndroidManifest.xml的属性 前面的xml信 ...
- 安卓H5软键盘遮挡输入框
由于安卓app内嵌入H5页面,webview对于软键盘没有处理(如果不是产品强烈要求建议不要处理这种拆东墙补西墙的问题,因为其他的手机上可能会出现已经优化软键盘的情况) 1.input下方还有多余空位 ...
- ios移动输入框被软键盘遮挡
页面输入框会出现被软键盘挡住的问题: 解决方法:获取input点击事件设置body高度 $('input').bind('click',function(e){ var $this = $(this) ...
随机推荐
- rails的接口查询详解
Retrieving Objects from the Database find "find"是一种常用的数据库查询方法,在Rails中被用于从数据库中查找单个记录.它可以接收一 ...
- 获取电脑的网络连接状态(三)Ping
网络连接判断,使用ping测试获取: 1 private static async Task<bool> IsPingSuccess() 2 { 3 try 4 { 5 using (Pi ...
- [C++提高编程] 1、模板
文章目录 1 模板 1.1 模板的概念 1.2 函数模板 1.2.1 函数模板语法 1.2.2 函数模板注意事项 1.2.3 函数模板案例 1.2.4 普通函数与函数模板的区别 1.2.5 普通函数与 ...
- Prism Sample 16-RegionContext
终于发现一个有趣的新知识了. 本例的核心是RegionContext,意思是一个区域的上下文.但与DataContext似乎并不相同. 先看一下整体思路. 在主窗体上只有一个Region: <G ...
- sqlilabs第一关
首先打开网页,进行注入点的测试 输入?id=1 and 1=1发现1=2的时候没有进行报错,有两种可能,一种是不能注入,第二种是字符型可以通过对字符型里面的''进行闭合,输入'and 1=1--+发现 ...
- 不是单例的单例——巧用ClassLoader
本文通过如何将一个单例类实例化两次的案例,用代码实践来引入 Java 类加载器相关的概念与工作机制.理解并熟练掌握相关知识之后可以扩宽解决问题的思路,另辟蹊径,达到目的. 背景 单例模式是最常用的设计 ...
- request args kwargs的作用
self.request : 包含了请求过来的对象 self.args:请求传递过来的参数,列表形式 self.kwargs:请求传递过来的参数,字典形式
- ToolStrip1
Private Sub ToolStrip1_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs) Handles Too ...
- java设计模式【抽象工厂模式】
java设计模式[抽象工厂模式] 抽象工厂模式 抽象工厂模式是对简单工厂模式的一个变种,它允许通过一个统一的接口来创建不同的产品实例,而无需指定具体的子类.在这个模式中,我们只关心产品的抽象接口,而将 ...
- 【熊子q的代码乐园】用python写个健康报备记录小系统
目录 一.前言 二.技术实现 1.概述 2. 环境 3. 技术核心 4. 数据库 5. 源代码 三.最后 一.前言 coding的一路上,遇到过许多问题,也写过一些代码去解决,回头看看还是有点意思的, ...