Android Dialog内容被底部导航栏遮挡问题定位解决

一、背景

    笔者在项目开发过程中,遇到了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带来的巨坑。希望能帮助到遇到同样问题的苦逼程序员们。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android 中实现类似微信底部状态栏的效果,可以通过使用 Dialog 来实现。下面是一个简单的示例: 1. 首先,在布局文件中创建一个包含底部状态栏的自定义布局(例如在底部有几个按钮和文本显示的布局)。 2. 在代码中创建一个自定义的 Dialog,使用上述布局。 3. 设置 Dialog 的样式,使其显示在屏幕的底部。 4. 使用 Dialog 的 show() 方法显示对话框。 例如: 1. 创建一个名为 dialog_bottom_status.xml 的布局文件,包含底部状态栏的按钮和文本。 ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:orientation="vertical"> <Button android:id="@+id/btn_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="状态按钮" /> <TextView android:id="@+id/text_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="状态文本" /> </LinearLayout> ``` 2. 创建一个名为 BottomStatusDialog 的类来实现自定义 Dialog。 ```java public class BottomStatusDialog extends Dialog { public BottomStatusDialog(Context context) { super(context); setContentView(R.layout.dialog_bottom_status); Button btnStatus = findViewById(R.id.btn_status); TextView textStatus = findViewById(R.id.text_status); // 在这里可以设置底部按钮和文本的点击事件和内容 // 设置对话框样式为底部显示 Window window = getWindow(); if (window != null) { window.setGravity(Gravity.BOTTOM); window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } } } ``` 3. 在需要显示底部状态栏的地方调用 BottomStatusDialog 的 show() 方法来显示对话框。 ```java BottomStatusDialog dialog = new BottomStatusDialog(this); dialog.show(); ``` 通过上述步骤,就可以实现一个类似微信底部状态栏的 Dialog。根据实际需求,你可以在布局文件和对话框类中添加其他的按钮和功能以满足你的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值