如何监听软键盘的弹出、隐藏(亲测可用)

看了N多文章,终于找到了答案

第一步

这篇文章解决了在不是全屏模式下,监听软键盘弹出隐藏,但是在全屏模式下,无效

注意:必须设置
android:windowSoftInputMode="adjustResize"

原理

注意下面的activityRootView对应的R.id.activityRoot,是你整个布局的根布局
原理就是通过判断手机屏幕的高度与你的根布局的高度的差值,作为判断软键盘,弹起、消失的依据
因为当 android:windowSoftInputMode=”adjustResize”`时,软键盘弹出时,会压缩你的根布局的显示高度。根据这个高度的前后变化,来反映软键盘的弹出和隐藏

但是,通过打印log可以发现当你的activity的主题使用了FullScreen之后你的根布局的高度,在软键盘弹出、隐藏时,就不变了,所以无法通过上述方法,判断监听软键盘事件,至于怎么解决的,看第二篇文章即可

如果你的activity不是采用FullScreen,使用第一种方法就可以

代码
  1. 直接在Activity里添加即可

    final View activityRootView = findViewById(R.id.activityRoot);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
            if (heightDiff > dpToPx(this, 200)) { 
                // 显示软键盘
            }else{
                //隐藏软键盘
                }
         }
    });
  2. 上面用到的dp转px方法

    public static float dpToPx(Context context, float valueInDp) {
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
        }

第二步

这篇文章,是基于第一篇文章的处理方案,成功解决了全屏模式下,监听软键盘弹出、隐藏

注意:必须设置
android:windowSoftInputMode="adjustResize"

很显然,通过写了一个类AndroidBug5497Workaround,使得上文说到的“你的根布局的高度”,在软键盘弹出、隐藏时候,发生了改变,从而监听了软键盘弹出、隐藏的事件
至于为什么加入这个类,会得到这个效果,我暂时还没有研究

  1. 写一个类

    public class AndroidBug5497Workaround {
    
        // For more information, see https://code.google.com/p/android/issues/detail?id=5497
        // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
    
        public static void assistActivity (Activity activity) {
            new AndroidBug5497Workaround(activity);
        }
    
        private View mChildOfContent;
        private int usableHeightPrevious;
        private FrameLayout.LayoutParams frameLayoutParams;
    
        private AndroidBug5497Workaround(Activity activity) {
            FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
            mChildOfContent = content.getChildAt(0);
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    possiblyResizeChildOfContent();
                }
            });
            frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
        }
    
        private void possiblyResizeChildOfContent() {
            int usableHeightNow = computeUsableHeight();
            if (usableHeightNow != usableHeightPrevious) {
                int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
                int heightDifference = usableHeightSansKeyboard - usableHeightNow;
                if (heightDifference > (usableHeightSansKeyboard/4)) {
                    // keyboard probably just became visible
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                } else {
                    // keyboard probably just became hidden
                    frameLayoutParams.height = usableHeightSansKeyboard;
                }
                mChildOfContent.requestLayout();
                usableHeightPrevious = usableHeightNow;
            }
        }
    
        private int computeUsableHeight() {
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            return (r.bottom - r.top);
        }
    
    }
  2. 在你的Activity里只需调用下面一句话即可

    AndroidBug5497Workaround.assistActivity(this);

下面贴出所有代码

  1. manifest.xml

    
    ......
    <activity
               android:theme="@style/AppTheme"
               android:name=".Main3Activity"android:windowSoftInputMode="adjustResize">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />
    
                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
           </activity>
         ......
  2. MainActivity(忽略我打印的那些log)

    public class Main3Activity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main3);
            AndroidBug5497Workaround.assistActivity(this);
            final LinearLayout activityRootView = (LinearLayout) findViewById(R.id.activity_main3);
            activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
                    if (heightDiff > dpToPx(Main3Activity.this, 150)) { // if more than 200 dp, it's probably a keyboard...
                        // ... do something here
                        Log.e("hhh","show------------");
                        Log.e("hhh","-----activityRootView.getRootView().getHeight()"+activityRootView.getRootView().getHeight());
                        Log.e("hhh","-----activityRootView.getHeight()"+activityRootView.getHeight());
    
                        Log.e("hhh","heightDiff------------"+heightDiff);
                        findViewById(R.id.ivv).setVisibility(View.GONE);
                    }else {
                        Log.e("hhh","hidden=============");
                        Log.e("hhh","=====activityRootView.getRootView().getHeight()"+activityRootView.getRootView().getHeight());
                        Log.e("hhh","=====activityRootView.getHeight()"+activityRootView.getHeight());
                        Log.e("hhh","heightDiff====="+heightDiff);
    
                        findViewById(R.id.ivv).setVisibility(View.VISIBLE);
                    }
                }
            });
        }
        public static float dpToPx(Context context, float valueInDp) {
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
        }
    }
    
  3. 神奇类 AndroidBug5497Workaround

        package com.demo.ruanjianpandemo;
    
        import android.app.Activity;
        import android.graphics.Rect;
        import android.view.View;
        import android.view.ViewTreeObserver;
        import android.widget.FrameLayout;
    
        public class AndroidBug5497Workaround {
    
            // For more information, see https://code.google.com/p/android/issues/detail?id=5497
            // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
    
            public static void assistActivity (Activity activity) {
                new AndroidBug5497Workaround(activity);
            }
    
            private View mChildOfContent;
            private int usableHeightPrevious;
            private FrameLayout.LayoutParams frameLayoutParams;
    
            private AndroidBug5497Workaround(Activity activity) {
                FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
                mChildOfContent = content.getChildAt(0);
                mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    public void onGlobalLayout() {
                        possiblyResizeChildOfContent();
                    }
                });
                frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
            }
    
            private void possiblyResizeChildOfContent() {
                int usableHeightNow = computeUsableHeight();
                if (usableHeightNow != usableHeightPrevious) {
                    int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
                    int heightDifference = usableHeightSansKeyboard - usableHeightNow;
                    if (heightDifference > (usableHeightSansKeyboard/4)) {
                        // keyboard probably just became visible
                        frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                    } else {
                        // keyboard probably just became hidden
                        frameLayoutParams.height = usableHeightSansKeyboard;
                    }
                    mChildOfContent.requestLayout();
                    usableHeightPrevious = usableHeightNow;
                }
            }
    
            private int computeUsableHeight() {
                Rect r = new Rect();
                mChildOfContent.getWindowVisibleDisplayFrame(r);
                return (r.bottom - r.top);
            }
    
        }
    
  4. 布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:orientation="vertical"
    
        tools:context="com.demo.ruanjianpandemo.Main3Activity">
    <ImageView
        android:id="@+id/ivv"
        android:src="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
        <com.demo.ruanjianpandemo.MyEditText
            android:id="@+id/myedittext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <com.demo.ruanjianpandemo.MyEditText
            android:id="@+id/myedittext1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值