首页 > 其他分享 >MAUI Blazor Android 输入框软键盘遮挡问题2.0

MAUI Blazor Android 输入框软键盘遮挡问题2.0

时间:2023-07-04 21:59:01浏览次数:61  
标签:int Rect 输入框 软键盘 static MChildOfContent MAUI Android rect

前言

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

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

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

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

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

1. 之前方案的整理

之前文章的代码有些乱,小大写以及空值判断都没有处理,强迫症表示很难受。

所以讨论新问题之前,先把之前的代码整理一遍。

using Android.Content.Res;
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;

[SupportedOSPlatform("Android")]
public static partial 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);
        if (MChildOfContent?.ViewTreeObserver == null) return;
        MChildOfContent.ViewTreeObserver.GlobalLayout += (s, o) => PossiblyResizeChildOfContent();
        FrameLayoutParams = (FrameLayout.LayoutParams?)MChildOfContent?.LayoutParameters;
    }

    static void PossiblyResizeChildOfContent()
    {
        if (MChildOfContent?.RootView == null) return;
        if (FrameLayoutParams == null) return;

        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);
        return rect.Bottom - rect.Top;
    }
}

Platforms/Android/MainActivity.cs中添加以下代码

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

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

问题展示

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

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

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

也就是代码中的这一部分

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

标签:int,Rect,输入框,软键盘,static,MChildOfContent,MAUI,Android,rect
From: https://www.cnblogs.com/Yu-Core/p/17525807.html

相关文章

  • 前端Vue自定义注册界面模版 手机号邮箱账号输入框 验证码输入框  包含手机号邮箱账号
    前端Vue自定义注册界面模版手机号邮箱账号输入框验证码输入框 包含手机号邮箱账号验证,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13306效果图如下:......
  • [MAUI]用纯C#代码写两个漂亮的时钟
    @目录时钟1绘制锯齿表盘绘制指针绘制沿路径文本时钟2绘制表盘绘制指针项目地址谷歌在2021年5月份推出的Android12给我们带来了新的UI设计规范MaterialYou,你是否已经体验到了MaterialYou设计的魅力了呢?在原生主屏幕启动器中,有一个时钟小部件。这个小部件可以选择表盘风格。......
  • 【C#/.NET】MAUI上的依赖注入
    ​引言        在移动应用开发中,依赖注入是一项非常重要的技术,它可以帮助我们简化代码结构、提高可维护性并增加测试覆盖率。在最新的.NET跨平台框架MAUI中,我们也可以利用依赖注入来构建高效的应用程序架构。本文将详细介绍在MAUI上如何使用依赖注入,旨在帮助开发者更好......
  • MAUI Blazor获取内存使用情况
    varrunTime=Java.Lang.Runtime.GetRuntime();varmaxMemory=runTime.MaxMemory();vartotalMemory=runTime.TotalMemory();varfreeMemory=runTime.FreeMemory();//获取可用内存ActivityManager.MemoryIn......
  • js原生方法:获取某个元素所处屏幕的位置,input输入框中文输入时的调用
    span.getBoundingClientRect()会返回改元素的位置信息//输入框内容改变functioninputSearchChange(){//如果是拼音输入,则会进入这个监听inputSearch.addEventListener('compositionstart',()=>{lastInputValue=inputSearch.valueisPinyin=true}......
  • 直播开发app,vue防抖 自定义ref实现输入框防抖
    直播开发app,vue防抖自定义ref实现输入框防抖 首先需要把input的双向绑定v-mode拆开为一个value和一个input事件,在事件里注册一个函数debUpdata,debUpdata里获取到input输入内容再赋值给text,这就类似于手写v-mode,代码如下: <template> <divclass="hello">  <inpu......
  • 【CSS】写一个原生的透明 input 标签输入框
    <divclass="search"> <imgsrc="@/assets/tools/search.svg"/> <inputplaceholder="搜索"@input="onSearch"v-model="searchValue"/></div>.search{ height:32px; width:204px; di......
  • elementplus vue 范围输入框
    <divclass="fv-rowmb-7"><labelclass="fs-6fw-semoboldmb-2">{{t("Numberofgroups")}}</label><el-form-itemprop="formInline.group"><el-inputcl......
  • 基于uni-app+vue3渲染markdown格式|uniapp软键盘顶起问题解决方案
    前些时候有给大家分享一篇uni-app+vite4+uview-plus搭建跨端项目。今天主要分享下在uniapp中渲染markdown语法及uniapp中软键盘弹起,页面tabbar或顶部自定义navbar导航栏被撑起挤压的问题。如上图:支持h5+小程序+App端markdown解析渲染。上面则是演示了在App端+小程序端键盘弹......
  • 前端Vue自定义支付密码输入键盘Keyboard和支付设置输入框Input
    前端Vue自定义支付密码输入键盘Keyboard和支付设置输入框Input,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13166效果图如下:cc-defineKeyboard使用方法<!--ref:唯一ref passwrdType:密码样式paykeyInfo:密码输入监测事件--><cc-def......