一、背景
笔者在项目开发过程中,遇到了Android Dialog内容被底部导航栏遮挡的问题。大致情况是这样的,项目需要一个全屏的对话框使用WebView显示内容,由于AndroidBug5497(大家可以搜索了解,大致就是全屏WebView,输入法软键盘会遮挡内容的问题),这边进行处理,处理之后,发现WebView内容被系统导航栏遮挡了一部分。因为特殊需求,需要保留底部导航栏,所以网上各种通过隐藏导航栏的方法也就不能使用了。
二、问题排查定位
2.1 AndroidBug5497处理
因为WebView内容有大量输入,因此输入法软键盘遮挡WebView的问题必须处理,处理代码如下。大致的做法就是监听输入法软键盘,根据输入法软键盘调整WebView的布局。
private static class KeyBoardListener {
private View mChildOfContent;
private int mUsableHeightPrevious;
private ViewGroup.LayoutParams mLayoutParams;
public KeyBoardListener(View contentView) {
mChildOfContent = contentView;
}
public void listen() {
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
mLayoutParams = (ViewGroup.LayoutParams) mChildOfContent.getLayoutParams();
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != mUsableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView()
.getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
mLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
mLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
mUsableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top + 100);
}
}
2.2 进一步分析
项目中为了使对话框能够全屏显示,对话框样式中使用了 <item name="android:windowIsFloating">false</item>(否则对话框会有边距,无法全屏),如此一来,问题就出现了。可是笔者项目中还有一处几乎一样的功能,全屏对话框使用WebView加载网页内容,没有出现遮挡的问题,代码各种对比了,都没有问题。最终发现唯一的不同就是,对话框的布局文件中根容器不一样。正常的根容器是RelativeLayout,出现被遮挡的根容器是 FrameLayout,实在没办法,将根容器改为 RelativeLayout,结果发现问题解决了。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFFFFFFF">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- .... -->
</RelativeLayout>
三、问题总结
经过这个案例,大致的结论就是,Dialog+windowIsFloating(false)+FrameLayout+全屏WebView+AndroidBug5497带来的巨坑。希望能帮助到遇到同样问题的苦逼程序员们。
文章讲述了开发者在Android项目中遇到的Dialog内容被底部导航栏和系统导航栏遮挡的问题,通过处理AndroidBug5497和调整布局(使用RelativeLayout而非FrameLayout)解决了冲突,总结为Dialog+windowIsFloating+FrameLayout+全屏WebView的常见问题点。
3381

被折叠的 条评论
为什么被折叠?



