场景1

问题描述

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

解决方案

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

    android:name="xxx"

    android:windowSoftInputMode="adjustPan"  />

adjustPan和 adjustResize的区别

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

场景2

问题描述

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

解决方案

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

场景3

问题描述

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

解决方案

方案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);

}

}

将该类新增到项目中,并在对应Activity的onCreate()方法中调用即可。

AndroidBug5497Workaround.assistActivity(this);

AndroidBug5497Workaround类解析:

通过findViewById(android.R.id.content)获取Activity界面开发者可控区域的根View。(全屏模式下,即为全部屏幕区域,非全屏模式下为除状态栏外区域) mChildOfContent = content.getChildAt(0); ,获取 Activity 布局的 View (即通过 setContentView() 设置的 View )。 View.getViewTreeObserver()获取一个专门监听当前View树变化的观察者对象。 由于软键盘的弹出,会使View树的全局布局(GlobalLayout)发生变化,所以给当前View树变化的观察者对象绑定监听addOnGlobalLayoutListener。 一旦触发addOnGlobalLayoutListener监听,主要则是调用possiblyResizeChildOfContent()方法,重置界面变化后可用区域。 possiblyResizeChildOfContent()方法中,heightDifference > (usableHeightSansKeyboard / 4)这个判断只有界面的高度变化超过1/4,才重置高度,确保响应软键盘的弹出,排除其他界面变化情况, computeUsableHeight()则是计算除去键盘后重新调整布局的可用高度。

软键盘遮挡界面问题总结

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

在无WebView的界面下: 按需求配置android:windowSoftInputMode,为adjustPan或adjustResize。 有WebView的界面下: 非全屏模式: 配置android:windowSoftInputMode为adjustResize。 全屏模式: 项目新增一个AndroidBug5497Workaround类,完美解决。

参考文章

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: