欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android获取软键盘高度

程序员文章站 2022-04-20 14:37:52
...

本文获取软键盘高度利用View里getWindowVisibleDisplayFrame (Rect outRect)方法,根据当软键盘弹出时所影响的outRect底部值bottom的偏差值来判断,现以为使bottom产生变化的有软键盘,虚拟导航键2种,所以区分此2种变化即可获取软键盘的高度,这里用了一个估计值,就是大于屏幕高度的1/4就以为是软键盘高度。取1/4这个比例主要还是考虑兼容全面屏,具体代码如下:

/**
 * 软键盘高度监听者,思路:当底部坐标变化超过整个屏幕的1/4即认为是这个偏差为软键盘高度
 */
public class KeyLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
    @NonNull
    private Activity mActivity;
    private int mScreenHeight;
    private Rect mOutRect = new Rect();
    private int mWindowVisibleDisplayFrameBottom;
    private OnGetKeyHeightListener onGetKeyHeightListener;

    public KeyLayoutListener(@NonNull Activity activity) {
        mActivity = activity;
        mScreenHeight = getScreenHeight();
    }

    @Override
    public void onGlobalLayout() {
        Window window = mActivity.getWindow();
        if (window == null)
            return;
        mOutRect.setEmpty();
        window.getDecorView().getWindowVisibleDisplayFrame(mOutRect);
        int offset = mWindowVisibleDisplayFrameBottom - mOutRect.bottom;
        if (offset > mScreenHeight / 4) {
            if (onGetKeyHeightListener != null) {
                onGetKeyHeightListener.onGet(offset);
            }
        } else {
            mWindowVisibleDisplayFrameBottom = mOutRect.bottom;
        }
    }

    private int getScreenHeight() {
        WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) {
            return mActivity.getResources().getDisplayMetrics().heightPixels;
        }
        Point point = new Point();
        if (Build.VERSION.SDK_INT >= 17) {
            wm.getDefaultDisplay().getRealSize(point);
        } else {
            wm.getDefaultDisplay().getSize(point);
        }
        return point.y;
    }

    public void setOnGetKeyHeightListener(OnGetKeyHeightListener onGetKeyHeightListener) {
        this.onGetKeyHeightListener = onGetKeyHeightListener;
    }

    public interface OnGetKeyHeightListener {
        void onGet(int keyBoardHeight);
    }
}

测试Activity的代码如下:

public class KeyboardActivity extends AppCompatActivity implements View.OnClickListener {

    private KeyLayoutListener mKeyLayoutListener;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_keyboard);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(this);
        mKeyLayoutListener = new KeyLayoutListener(this);
        mKeyLayoutListener.setOnGetKeyHeightListener(new KeyLayoutListener.OnGetKeyHeightListener() {
            @Override
            public void onGet(int keyBoardHeight) {
                Log.i("KeyboardActivity", "keyBoardHeight:" + keyBoardHeight);
            }
        });
        getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(mKeyLayoutListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mKeyLayoutListener != null) {
            getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(mKeyLayoutListener);
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.button) {
            Log.i("KeyboardActivity", "isSoftShowing:" + isSoftShowing());
        }
    }

    private boolean isSoftShowing() {
        //获取当前屏幕内容的高度
        int screenHeight = getWindow().getDecorView().getHeight();
        //获取View可见区域的bottom
        Rect rect = new Rect();
        //DecorView即为activity的*view
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        //考虑到虚拟导航栏的情况(虚拟导航栏情况下:screenHeight = rect.bottom + 虚拟导航栏高度)
        //选取screenHeight*3/4进行判断
        return screenHeight * 3 / 4 > rect.bottom;
    }

}

最后再附上activity_keyboard.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取状态" />

</LinearLayout>