android软键盘遮挡WebView中input的解决方案
程序员文章站
2022-03-02 14:37:01
...
现象
在做hybrid应用时,我们用WebView来加载html页面,经常会出现软件盘弹出,遮挡了html中输入控件(如input)的问题。
无论你是用系统的原生WebView(从4.0-7.0),还是Crosswalk的XWalkView,都有这个问题! (用系统原生浏览器是没有这个问题的)
这里不得不吐槽一下,ios没有这个问题。
解决方案有以下几种:
- 软键盘弹出时WebView高度缩小。
- 软键盘弹出时,WebView内容适当上移。
个人比较喜欢第二个方案,因为:
- 与IOS体验一致
- 页面不需要重新布局,避免了有些页面在WebView高度缩小后,布局样式体验不好;
1 软键盘弹出时WebView高度缩小(网上大多数也都是说的这个方案)
设置页面adjustResize
android:windowSoftInputMode="adjustResize"
原理是软件盘弹出时,整个页面的大小都缩小了,软键盘不再遮挡WebView了,这个问题自然也就不存在了。
这个方案最简单。但有时不太好用,如果页面是上下有固定布局,中间滚动区域(如上标题栏,下方操作按钮,中间是可以滚动的信息输入区域)。点击中间滚动区域的输入框,软键盘弹出,会把底部布局也顶上去,导致中间滚动区域可能高度很小了,显示效果很差。一
一个办法是软键盘弹出时,底部布局隐藏。
window.addEventListener("resize", (v) => {
this.LastWindowHeight = this.CurWindowHeight;
this.CurWindowHeight = window.innerHeight;
if ((this.LastWindowHeight - this.CurWindowHeight) /this.LastWindowHeight > 0.25){
//hide bottom buttons
}else{
//display bottom buttons
}
});
2 软键盘弹出时,WebView内容适当上移
软键盘弹出时,WebView可视区域变小了,可以计算WebView的实际高度,可视高度,将这些数据传入js,js层根据当前的焦点位置,根据需要上移body。
android:windowSoftInputMode="adjustPan"
public static class HeightVisibleChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {
private WebView webview;
public HeightVisibleChangeListener(WebView webView){
this.webview = webView;
webview.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
int lastHeight;
int lastVisibleHeight;
@Override
public void onGlobalLayout() {
Rect visible = new Rect();
Rect size = new Rect();
webview.getWindowVisibleDisplayFrame(visible);
webview.getHitRect(size);
int height = size.bottom-size.top;
int visibleHeight = visible.bottom - visible.top;
if(height == lastHeight && lastVisibleHeight == visibleHeight) return;
lastHeight = height;
lastVisibleHeight = visibleHeight;
String js = String.format("javascript:heightChange(%1$d , %2$d)",height,visibleHeight);
webview.loadUrl(js);
}
};
初始化webview的时候,初始化一下这个类即可。
new HeightVisibleChangeListener(webView);
上层代码,这里用的是ts
export class KeyboardUtil {
private static height:number;
private static visibleHeight:number;
//android adjustpan 模式下,软键盘遮挡输入框。
static FixAndroidKeyBoardHideInput(){
window['heightChange'] = (height :number , visibleHeight:number)=>{
KeyboardUtil.OnHeightChange(height,visibleHeight);
}
}
static OnHeightChange(height :number , visibleHeight:number):void{
const body = document.body;
KeyboardUtil.height = body.clientHeight;
KeyboardUtil.visibleHeight = visibleHeight * body.clientHeight /height;
const active = document.activeElement as HTMLElement;
if(height == visibleHeight){
KeyboardUtil.SetElementScrollTop(body , 0);
return;
}
let focusTopRelateWindow = KeyboardUtil.FindElementPositionRelateToWindow(active);
let focusBottomRelateWindow = focusTopRelateWindow + active.clientHeight;
const mindistince = 50;
let bottom = focusBottomRelateWindow + mindistince;
if(bottom > KeyboardUtil.height) bottom = KeyboardUtil.height;
const offset = bottom - KeyboardUtil.visibleHeight;
if(offset <=0){
KeyboardUtil.SetElementScrollTop(body , 0);
return;
}
KeyboardUtil.SetElementScrollTop(body , offset);
}
static SetElementScrollTop(e : HTMLElement , offset : number){
if(offset == 0){
e.style.top = '0';
}else{
e.style.top = '-'+offset +'px';
}
}
static FindElementPositionRelateToWindow(element: HTMLElement) {
let curtop = 0;
let curtopscroll = 0;
if (element.offsetParent) {
do {
curtop += element.offsetTop;
curtopscroll += element.offsetParent ? element.offsetParent.scrollTop : 0;
} while (element = element.offsetParent as HTMLElement);
}
return curtop - curtopscroll;
}
}
上一篇: Spring2.5整合JPA(转)
下一篇: 沉浸式和软键盘冲突
推荐阅读
-
Android 中的webview组件显示vue空白的解决方案
-
Android开发软键盘遮挡登陆按钮的完美解决方案
-
android 关于软键盘遮挡webView底部输入框问题(解决方案)
-
javascript - 怎么解决苹果5中input获取焦点,软键盘遮挡input的问题
-
javascript - 怎么解决苹果5中input获取焦点,软键盘遮挡input的问题
-
Android软键盘遮挡的四种解决方案
-
Android WebView中软键盘会遮挡输入框相关问题
-
Android实战开发篇 Android软键盘遮挡的解决方案
-
android软键盘遮挡WebView中input的解决方案
-
解决Android中Webview软键盘与沉浸式的冲突的几种方式的分析