看了N多文章,终于找到了答案
第一步
这篇文章解决了在不是全屏模式下,监听软键盘弹出隐藏,但是在全屏模式下,无效
注意:必须设置
android:windowSoftInputMode="adjustResize"
原理
注意下面的activityRootView对应的R.id.activityRoot,是你整个布局的根布局
原理就是通过判断手机屏幕的高度与你的根布局的高度的差值,作为判断软键盘,弹起、消失的依据
因为当 android:windowSoftInputMode=”adjustResize”`时,软键盘弹出时,会压缩你的根布局的显示高度。根据这个高度的前后变化,来反映软键盘的弹出和隐藏但是,通过打印log可以发现当你的activity的主题使用了FullScreen之后你的根布局的高度,在软键盘弹出、隐藏时,就不变了,所以无法通过上述方法,判断监听软键盘事件,至于怎么解决的,看第二篇文章即可
如果你的activity不是采用FullScreen,使用第一种方法就可以
代码
直接在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{ //隐藏软键盘 } } });
上面用到的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,使得上文说到的“你的根布局的高度”,在软键盘弹出、隐藏时候,发生了改变,从而监听了软键盘弹出、隐藏的事件
至于为什么加入这个类,会得到这个效果,我暂时还没有研究
写一个类
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); } }
在你的Activity里只需调用下面一句话即可
AndroidBug5497Workaround.assistActivity(this);
下面贴出所有代码
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> ......
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); } }
神奇类 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); } }
布局
<?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>