Android键盘监听工具类

  • 将状态栏透明后(沉浸式),导致键盘模式失效,无法自动将输入框上移,所以需要监听页面的高度变化的差值,从而计算出键盘高度,手动将底部的输入框上移
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

/// 键盘监听工具类
public final class KeyboardUtil {
    public static void hideKeyboard(Activity activity) {
        InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputMethodManager != null) {
            inputMethodManager.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
        }
    }

    // 注册键盘监听
    public static void registerKeyboardStateCallback(
            @NonNull LifecycleOwner lifecycleOwner,
            @NonNull Activity activity,
            @NonNull KeyboardStateCallback callback
    ) {
        new KeyboardStateWatcher(lifecycleOwner, activity, callback);
    }

    public interface KeyboardStateCallback {
        void onShow(int keyboardHeight);

        void onHide();
    }

    private static class KeyboardStateWatcher implements LifecycleEventObserver, ViewTreeObserver.OnGlobalLayoutListener {

        private final Rect windowVisibleRect = new Rect();

        private final Lifecycle lifecycle;

        private View rootView;

        private KeyboardStateCallback callback;

        private int rootViewVisibleHeight = 0;

        public KeyboardStateWatcher(@NonNull LifecycleOwner lifecycleOwner, @NonNull Activity activity, @NonNull KeyboardStateCallback callback) {
            this.lifecycle = lifecycleOwner.getLifecycle();
            this.lifecycle.addObserver(this);

            this.rootView = activity.getWindow().getDecorView();
            this.rootView.getViewTreeObserver().addOnGlobalLayoutListener(this);

            this.callback = callback;
        }

        private void analyzeKeyboardState(View rootView) {
            rootView.getWindowVisibleDisplayFrame(windowVisibleRect);
            int visibleHeight = windowVisibleRect.height();
            if (rootViewVisibleHeight == 0) {
                rootViewVisibleHeight = visibleHeight;
                return;
            }
            if (rootViewVisibleHeight == visibleHeight) {
                return;
            }
            if (rootViewVisibleHeight - visibleHeight > 200) {
                callback.onShow(rootViewVisibleHeight - visibleHeight);
                rootViewVisibleHeight = visibleHeight;
            } else if (visibleHeight - rootViewVisibleHeight > 200) {
                callback.onHide();
                rootViewVisibleHeight = visibleHeight;
            }
        }

        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            if (event == Lifecycle.Event.ON_DESTROY) {
                rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                lifecycle.removeObserver(this);

                rootView = null;
                callback = null;
            }
        }

        @Override
        public void onGlobalLayout() {
            analyzeKeyboardState(rootView);
        }
    }
}
  • 简单使用
    KeyboardUtil.registerKeyboardStateCallback(this, this, new KeyboardUtil.KeyboardStateCallback() {
    @Override
    public void onShow(int keyboardHeight) {
        // 键盘弹起,让底部输入框向上移动
        binding.editText.setTranslationY(-keyboardHeight);
    }

    @Override
    public void onHide() {
        // 键盘隐藏
    }
});
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容