Android两层布局,键盘弹出时,底层保持不动,上层顶上去

参考项目KeyboardVisibilityEvent

1、AndroidManifest.xml中activity不设置android:windowSoftInputMode属性或者设置为adjustUnspecified

2、修改过后的KeyboardVisibilityEvent代码

public class KeyboardVisibilityEvent {

    private final static int KEYBOARD_VISIBLE_THRESHOLD_DP = 100;

    /**
     * Set keyboard visibility change event listener.
     *
     * @param activity Activity
     * @param listener KeyboardVisibilityEventListener
     */
    public static void setEventListener(final Activity activity, final boolean isFullScreen,
                                        final KeyboardVisibilityEventListener listener) {

        if (activity == null) {
            throw new NullPointerException("Parameter:activity must not be null");
        }

        if (listener == null) {
            throw new NullPointerException("Parameter:listener must not be null");
        }

        final View activityRoot = getActivityRoot(activity);

        activityRoot.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {

                    private final Rect rootViewRect = new Rect();

                    private final int visibleThreshold = getVisibleThreshold(activity);

                    private boolean wasOpened = false;

                    @Override
                    public void onGlobalLayout() {
                        activityRoot.getWindowVisibleDisplayFrame(rootViewRect);

                        int heightDiff = activityRoot.getRootView().getHeight() - rootViewRect.height();
                        if(!isFullScreen)
                        {
                            heightDiff -= getStatusBarHeight(activity);
                        }

                        boolean isOpen = heightDiff > visibleThreshold;

                        if (isOpen == wasOpened) {
                            // keyboard state has not changed
                            return;
                        }

                        wasOpened = isOpen;

                        listener.onVisibilityChanged(isOpen, heightDiff);
                    }
                });
    }

    /**
     * Determine if keyboard is visible
     *
     * @param activity Activity
     * @return Whether keyboard is visible or not
     */
    public static boolean isKeyboardVisible(Activity activity) {
        Rect r = new Rect();

        View activityRoot = getActivityRoot(activity);
        int visibleThreshold = getVisibleThreshold(activity);

        activityRoot.getWindowVisibleDisplayFrame(r);

        int heightDiff = activityRoot.getRootView().getHeight() - r.height();

        return heightDiff > visibleThreshold;
    }

    public static int getVisibleThreshold(Context context)
    {
        return  Math.round(UIUtil.convertDpToPx(context, KEYBOARD_VISIBLE_THRESHOLD_DP));
    }

    private static View getActivityRoot(Activity activity) {
        return ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
    }

    private static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
}

3、布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout  android:id="@+id/rl_bottom"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:gravity="center_horizontal|top"
            android:layout_alignParentTop="true"
            android:text="顶部"
            android:textColor="#ff0000"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:text="中间"
            android:textColor="#ff0000"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:gravity="center_horizontal|bottom"
            android:layout_alignParentBottom="true"
            android:text="底部"
            android:textColor="#ff0000"/>
    </RelativeLayout>

    <RelativeLayout android:id="@+id/rl_top"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/keyboard_status"
            android:text="@string/hello_world"
            android:layout_alignParentTop="true"
            android:layout_width="match_parent"
            android:gravity="center"
            android:textSize="30sp"
            android:layout_height="100dp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#660000ff"
                android:gravity="center_vertical"
                android:orientation="horizontal">
                <TextView
                    android:id="@+id/button"
                    android:text="点我点我"
                    android:gravity="center"
                    android:layout_alignParentTop="true"
                    android:layout_width="wrap_content"
                    android:layout_height="40dp" />

                <EditText
                    android:id="@+id/text_field"
                    android:layout_alignParentBottom="true"
                    android:layout_width="match_parent"
                    android:layout_height="40dp" />
            </LinearLayout>

            <TextView
                android:gravity="center"
                android:background="#6600ff00"
                android:layout_width="match_parent"
                android:layout_height="60dp" />
        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

4、MainActivity代码

public class MainActivity extends AppCompatActivity {

    TextView mKeyboardStatus;

    EditText mTextField;
    TextView button;
    RelativeLayout rlBottom;
    RelativeLayout rlTop;
    int mKh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mKeyboardStatus = (TextView) findViewById(R.id.keyboard_status);
        mTextField = (EditText) findViewById(R.id.text_field);
        button = (TextView) findViewById(R.id.button);
        rlTop = (RelativeLayout) findViewById(R.id.rl_top);
        rlBottom = (RelativeLayout) findViewById(R.id.rl_bottom);

        KeyboardVisibilityEvent.setEventListener(this, false, new KeyboardVisibilityEventListener() {
            @Override
            public void onVisibilityChanged(boolean isOpen, int kh) {
                updateKeyboardStatusText(isOpen);

                Log.i("aaaaaaaaaaaaab", "isOpen: " + isOpen + "  kh: " + kh);

                if(isOpen)
                {
                    RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) rlTop.getLayoutParams();
                    p.height = rlBottom.getHeight() - kh;
                    rlTop.setLayoutParams(p);

                    if(kh > KeyboardVisibilityEvent.getVisibleThreshold(MainActivity.this))
                    {
                        mKh = kh;
                    }
                }
                else
                {
                    RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) rlTop.getLayoutParams();
                    p.height = rlBottom.getHeight();
                    rlTop.setLayoutParams(p);
                }

            }
        });

        button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) rlTop.getLayoutParams();
                        p.height = rlBottom.getHeight() - (mKh > 200 ? mKh : 600);
                        rlTop.setLayoutParams(p);

                        UIUtil.showKeyboard(MainActivity.this, mTextField);
                    }
                });

        updateKeyboardStatusText(KeyboardVisibilityEvent.isKeyboardVisible(this));
    }

    private void updateKeyboardStatusText(boolean isOpen) {
        mKeyboardStatus.setText(String.format("keyboard is %s", (isOpen ? "visible" : "hidden")));
    }

}

5、如果有可滚动view的话,DecorView会resize,所有要监听DecorView变化。

  final ViewGroup activityRoot = ((ViewGroup) findViewById(android.R.id.content));
        activityRoot.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {

                    @Override
                    public void onGlobalLayout() {
                        Log.i("aaaaaaaaaaaaab", "activityRoot: " + activityRoot.getHeight() + "-" + mDecorViewHeight);
                        if(activityRoot.getHeight() < mDecorViewHeight)
                        {
                            Log.i("aaaaaaaaaaaaab", "set activityRoot: ");
                            ViewGroup.LayoutParams p = (ViewGroup.LayoutParams) activityRoot.getLayoutParams();
                            p.height = mDecorViewHeight;
                            activityRoot.setLayoutParams(p);
                        }
                    }
                });

转载于:https://my.oschina.net/bruces/blog/731663

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值