监听根layout变化

主要利用View.getViewTreeObserver().addOnGlobalLayoutListener()

记录decorView的高度。在decorView高度变化时,可对其子视图做一些操作。

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="@dimen/health_plan_info_root_margin_bottom"
    android:layout_marginTop="63dp">
  <!-- 其他东西 -->
</RelativeLayout>

一个伪装成dialog的activity,监听软键盘弹出时它的高度变化。 软键盘弹出时,会把activity顶上去。此时可以动态改变activity的marginBottom。

private View mRootLayout; // layout中的底layout
private int mRootViewHeight = 0; // 根视图的高度

    private void initSoftKeyboardController() {
        final View decorView = getWindow().getDecorView();
        decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                decorView.getWindowVisibleDisplayFrame(r);
                int visibleHeight = r.height();
                if (mRootViewHeight == 0) {
                    mRootViewHeight = visibleHeight; // 记录根视图高度
                    return;
                }
                if (mRootViewHeight == visibleHeight) {
                    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mRootLayout.getLayoutParams();
                    params.bottomMargin = getResources().getDimensionPixelOffset(R.dimen.health_plan_info_root_margin_bottom);
                    mRootLayout.setLayoutParams(params);
                    return;
                }
                if (mRootViewHeight - visibleHeight > 200) { // 超过这个值则把底部间隔设为0
                    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mRootLayout.getLayoutParams();
                    params.bottomMargin = 0;
                    mRootLayout.setLayoutParams(params);
                }
            }
        });
    }

decorView是一个FrameLayout。获取LayoutParams时要注意。

这个dialog样式的activity的style

    <style name="dialog_style" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <!--设置dialog的背景-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--设置Dialog的windowFrame框为无-->
        <item name="android:windowFrame">@null</item>
        <!--设置无标题-->
        <item name="android:windowNoTitle">true</item>
        <!--是否浮现在activity之上-->
        <item name="android:windowIsFloating">true</item>
        <!--是否半透明-->
        <item name="android:windowIsTranslucent">true</item>
        <!--设置窗口内容不覆盖-->
        <item name="android:windowContentOverlay">@null</item>
        <!--设置动画,在这里使用让它继承系统的Animation.Dialog-->
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <!--背景是否模糊显示-->
        <item name="android:backgroundDimEnabled">true</item>
    </style>