Android全局监听键盘弹出/收起事件,支持在任何类

源码地址:https://github.com/HuCanui/KeyboradObserver

最近发现公司的app右下角有个小悬浮窗,这个悬浮窗是在Service里面控制显示隐藏的,当键盘弹窗输入时会影响输入。追求完美的我实在看不下去了,给自己提了个需求键盘弹出时隐藏悬浮窗,键盘退出时继续显示。
来!实现一把。通常做法实在activity里面去获取顶级View,然后设置监听OnGlobalLayoutListener,onGlobalLayout的时候检查下顶级View实际的高度是不是比实际的可见的高度大100dp。默认键盘高度大于100dp。

final View activityRoot = getWindow().getDecorView();
                    if (activityRoot == null) {
                        return;
                    }
                    ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {

                        private final Rect r = new Rect();
                        private final int visibleThreshold = Math.round(dp2px(activity, 100));

                        @Override
                        public void onGlobalLayout() {
                            activityRoot.getWindowVisibleDisplayFrame(r);
                            int heightDiff = activityRoot.getRootView().getHeight() - r.height();
                            //键盘是否弹出
                            boolean isOpen = heightDiff > visibleThreshold;

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

但。。。是,现在是在Service里面,我ca,怎么拿到当前页面RootView。不好意思,夸张了?,还是有很多办法拿到的,比如:在application里面注册Application.ActivityLifecycleCallbacks,onActivityCreated的把activity缓存起来不就好了,能拿到当前Activity,不就可以拿到当前页面RootView了,然后再去设置OnGlobalLayoutListener监听。
能拿到当前页面RootView了也不顶事啊,在Service里面,我就想有人在实时通知我:嘿!键盘弹出啦!嘿!键盘退出啦。
叮咚,EventBus各位大佬应该用得多了吧,我们在RootView
onGlobalLayout的时候检查键盘是否弹出了,然后再发个事件出来也不是什么难事。

application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            private boolean wasOpened = false;
           private final static int KEYBOARD_VISIBLE_THRESHOLD_DP = 100;
            @Override
            public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {
                try {
                    final View activityRoot = getActivityRoot(activity);
                    if (activityRoot == null) {
                        return;
                    }
                    ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {

                        private final Rect r = new Rect();
                        private final int visibleThreshold = Math.round(dp2px(activity, KEYBOARD_VISIBLE_THRESHOLD_DP));

                        @Override
                        public void onGlobalLayout() {
                            activityRoot.getWindowVisibleDisplayFrame(r);
                            int heightDiff = activityRoot.getRootView().getHeight() - r.height();
                            boolean isOpen = heightDiff > visibleThreshold;

                            if (isOpen == wasOpened) {
                                // keyboard state has not changed
                                return;
                            }
                            wasOpened = isOpen;
                            //发个事件
                            EventBus.getDefault().post(new KeyboardVisibleEvent(isOpen));
                        }
                    };

                    activityRoot.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            @Override
            public void onActivityStarted(Activity activity) {
            }

            @Override
            public void onActivityResumed(Activity activity) {
            }

            @Override
            public void onActivityPaused(Activity activity) {
            }

            @Override
            public void onActivityStopped(Activity activity) {
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });

然后我做了点简单的小封装,添加了OnGlobalLayoutListener,remove下总是比较友好的,再增加个手动调用方法判断键盘是否正在展示的方法。使用起来就方便多了。不用到处去设置OnGlobalLayoutListener了。支持在任何类里监听键盘事件。
源码地址:https://github.com/HuCanui/KeyboradObserver

使用: 1、在Application的onCreate的时候

       KeyboardVisibilityObserver.getInstance().init(this);

2、EventBus开源库加下

       implementation 'org.greenrobot:eventbus:3.1.1'

3、在需要监听键盘的事件的类里面注册/反注册下EventBus

       EventBus.getDefault().register(this);
       EventBus.getDefault().unregister(this);

4、键盘事件监听下

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(KeyboardVisibleEvent event){
        Toast.makeText(this, event.isVisible ? "键盘弹起" : "键盘收起", Toast.LENGTH_SHORT).show();
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值