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) ...
随机推荐
- 15-js语法检查eslint
const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); modul ...
- Network Science: 巴拉巴西网络科学阅读笔记
前言: 最小生成树中Kruskal算法对应了统计物理中的著名模型invasion percolation.由此写了一篇文章:invasion percolation and global optimi ...
- HDCTF_2023
pwnner 附件 有后门函数,seed是一个固定值, //伪随机数 #include <stdio.h> #include <stdlib.h> int main() { i ...
- vue2项目中调取登录接口登录以后获取个人信息以后,储存在哪里,怎么在不同的页面展示想要的信息?
在Vue2项目中,可以将个人信息存储在Vuex状态管理中或者浏览器的本地存储中,具体取决于项目的需求和规模. 1. Vuex状态管理 在Vuex中定义一个user模块,用于存储用户信息,可以在登录成功 ...
- 你还弄不清xxxForCausalLM和xxxForConditionalGeneration吗?
Part1基本介绍 大语言模型目前一发不可收拾,在使用的时候经常会看到transformers库的踪影,其中xxxCausalLM和xxxForConditionalGeneration会经常出现在我 ...
- [C++核心编程] 3、函数提高
文章目录 3 函数提高 3.1 函数默认参数 3.2 函数占位参数 3.3 函数重载 3.3.1 函数重载概述 3.3.2 函数重载注意事项 3 函数提高 3.1 函数默认参数 在C++中,函数的形参 ...
- 2022-04-17:给定一个数组arr,其中的值有可能正、负、0, 给定一个正数k。 返回累加和>=k的所有子数组中,最短的子数组长度。 来自字节跳动。力扣862。
2022-04-17:给定一个数组arr,其中的值有可能正.负.0, 给定一个正数k. 返回累加和>=k的所有子数组中,最短的子数组长度. 来自字节跳动.力扣862. 答案2022-04-17: ...
- Golang指针隐式间接引用
1.Golang指针 在介绍Golang指针隐式间接引用前,先简单说下Go 语言的指针 (Pointer),一个指针可以指向任何一个值的内存地址 它指向那个值的内存地址,在 32 位机器上占用 4 个 ...
- structed streaming 触发器trigger
structed streaming的执行批次,较spark streaming有所改变.更加灵活.总结下来,可大白话地分为三类: 1尽可能快的执行,不定时间 2按固定间隔时间执行 3仅执行一次 详情 ...
- 补充:C语言枚举类型
1.枚举类型 1.枚举数据类型是C语言中一种构造数据类型,可以让数据更加简洁,更易读,对于只有几个特定的数据,可以使用枚举类型 2.枚举对应英文enumeration,简写为enum 3.枚举是一组常 ...