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) ...
随机推荐
- TENGSHE-OS-渗透测试系统-win11版
下载ISO文件 创建新的虚拟机 VM17 已支持直接创建 win11 x64 稍后安装系统 选中win11 修改路径 win11需要设置8位加密密码 勾选安全引导 根据自身情况选择 默认即可 150G ...
- python pyinstaller库
简要 pyinstaller模块主要用于python代码打包成exe程序直接使用,这样在其它电脑上即使没有python环境也是可以运行的. 用法 一.安装 pyinstaller属于第三方库,因此在使 ...
- 学习笔记——树形dp
树形 dp 介绍 概念 树形 dp,顾名思义,就是在树上做 dp,将 dp 的思想建立在树状结构之上. 常见的树形 dp 有两种转移方向: 从叶节点向根节点转移,这种也是树形 dp 中较为常见的一种. ...
- 自定义alert、confirm、prompt的vue组件
Prompt.vue组件 说明: 通过props定制定制的Prompt,可选值 mode 默认值:prompt, 其他模式:confirm.message(简单的提示,可设置提示显示时间,类似aler ...
- 2022-05-03:Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中 stones[i] 是第
2022-05-03:Alice 和 Bob 再次设计了一款新的石子游戏.现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值.给你一个整数数组 stones ,其中 stones[i] 是第 ...
- 2021-07-05:股票问题2。给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖
2021-07-05:股票问题2.给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格.设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖 ...
- ET介绍——CSharp协程
什么是协程 说到协程,我们先了解什么是异步,异步简单说来就是,我要发起一个调用,但是这个被调用方(可能是其它线程,也可能是IO)出结果需要一段时间,我不想让这个调用阻塞住调用方的整个线程,因此传给被调 ...
- c#优雅高效的读取字节数组——不安全代码(1)
在开发上位机的经历中,会有很多需要和下位机交互通信的场景,大多数都会定义一个和硬件的通信协议,最终在上位机代码中的形式其实就是符合通信协议的字节数组. 目录 场景 如何解析字节数组到类或结构体中 建立 ...
- C#设计模式19——装饰器模式的写法
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责,而不需要修改这个对象的代码. What(什么) 装饰器模式是一种结构型设计模式,它允许 ...
- Redis系列16:聊聊布隆过滤器(原理篇)
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...