Android 软键盘遮挡界面问题汇总

场景1

问题描述

常规的,当点击EditText输入框时,软键盘弹出,但键盘会遮挡EditText显示。

解决方案

AndroidManifest文件中,Activity新增配置android:windowSoftInputMode,设置值为adjustPanadjustResize,如下:

<activity
    android:name="xxx"
    android:windowSoftInputMode="adjustPan"  />
adjustPan和 adjustResize的区别
  • adjustPan配置该参数,整个界面会向上平移,显示输入框,但不改变界面的布局。
  • adjustResize配置该参数,系统会重新计算除去软键盘后的界面尺寸,**用更少的界面区域显示内容,**输入框也在其中。



场景2

问题描述

混合开发中,应用在非全屏模式下,WebView加载网页,点击输入框,软键盘遮挡问题。

解决方案

操作方法同上,但是只支持设置值为adjustResize,设置 adjustPan无效。



场景3

问题描述
  • 混合开发中,应用在全屏模式下(Application或activity使用Fullscreen主题、沉浸式状态栏、Immersive Mode等),WebView加载网页,点击输入框,软键盘遮挡问题。
  • android:windowSoftInputMode设置值为adjustPanadjustResize均无效。
  • 这是系统级别的一个坑。
解决方案
方案1

当一个Activity中包含WebView控件时,尽量避免使用全景模式。(当然这个方法治标不治本)

方案2

stackflow上有个大牛提供了解决方案。(stackflow地址

具体代码如下,

import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

/**
 * 修复WebView全屏模式下,软键盘遮挡问题
 */
public final class AndroidBug5497Workaround {
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private int contentHeight;
    private boolean isFirst = true;
    private int statusBarHeight;

    public static void assistActivity(Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private AndroidBug5497Workaround(Activity activity) {
        //获取状态栏的高度
        int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
        statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        //界面出现变动都会调用这个监听事件
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                if (isFirst) {
                    contentHeight = mChildOfContent.getHeight();//兼容华为等机型
                    isFirst = false;
                }
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    /**
     * 重新调整布局的高度
     */
    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        //当前可见高度和上一次可见高度不一致 布局变动
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard / 4)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
                } else {
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                }
            } else {
                frameLayoutParams.height = contentHeight;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    /**
     * 计算mChildOfContent可见高度
     *
     * @return
     */
    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}
  • 将该类新增到项目中,并在对应ActivityonCreate()方法中调用即可。
        AndroidBug5497Workaround.assistActivity(this);

AndroidBug5497Workaround类解析:

  1. 通过findViewById(android.R.id.content)获取Activity界面开发者可控区域的根View。(全屏模式下,即为全部屏幕区域,非全屏模式下为除状态栏外区域

  2. mChildOfContent = content.getChildAt(0); ,获取 Activity 布局的 View (即通过 setContentView() 设置的 View )。

  3. View.getViewTreeObserver()获取一个专门监听当前View树变化的观察者对象

  4. 由于软键盘的弹出,会使View树的全局布局(GlobalLayout)发生变化,所以给当前View树变化的观察者对象绑定监听addOnGlobalLayoutListener

  5. 一旦触发addOnGlobalLayoutListener监听,主要则是调用possiblyResizeChildOfContent()方法,重置界面变化后可用区域。

  6. possiblyResizeChildOfContent()方法中,heightDifference > (usableHeightSansKeyboard / 4)这个判断只有界面的高度变化超过1/4,才重置高度,确保响应软键盘的弹出,排除其他界面变化情况,

  7. computeUsableHeight()则是计算除去键盘后重新调整布局的可用高度。



软键盘遮挡界面问题总结

Android输入框软键盘遮挡问题,通常有以下三种情况:

  • 在无WebView的界面下:
    按需求配置android:windowSoftInputMode,为adjustPanadjustResize

  • 有WebView的界面下:
    非全屏模式:
    配置android:windowSoftInputModeadjustResize
    全屏模式:
    项目新增一个AndroidBug5497Workaround类,完美解决。

参考文章

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,当软键盘弹出时,有时会出现软键盘遮挡按钮的情况。有几种方法可以解决这个问题。 首先,可以尝试使用WindowSoftInputMode属性来调整布局。根据引用[2]中的解释,可以尝试将属性设置为"adjustPan|stateHidden"或"adjustResize|stateHidden"。然而,根据引用的测试结果,这种设置对于某些布局可能没有效果。这意味着软键盘仍然可能遮挡按钮。 其次,可以考虑使用ScrollView来解决软键盘遮挡问题。根据引用中的解释,在登录界面开发中,当点击EditText准备输入时,弹出的软键盘可能会遮挡按钮或下方的输入框。为了解决这个问题,可以将整个布局放在ScrollView中,这样当软键盘弹出时,布局会自动上移以保证按钮的可见性。 请注意,解决软键盘遮挡问题可能需要根据具体的布局和需求进行调整和测试。以上方法只是一些常见的解决方案,可以根据实际情况选择合适的方法来解决软键盘遮挡按钮的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Android软键盘遮挡问题解决](https://blog.csdn.net/lintax/article/details/53365141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值