完美解决android软键盘监听
Posted ADark0915
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完美解决android软键盘监听相关的知识,希望对你有一定的参考价值。
最近在做应用性能调优,发现在一个包含有输入框的Activity中,当软键盘弹出的时候,如果直接finish掉此Activity,那么在返回到上一个Activity时,界面的渲染会由于软键盘没有及时的收起而出现卡顿的情况。
很不友好。
于是,本着geek的精神,做就做到极致,就尝试着对这一块做优化。
借助网上一些知识的分享,同时结合自己的理解,最终应用到项目中。
直接上代码。。
首先,在manifest文件中声明此Activity的windowSoftInputMode属性,
1 android:windowSoftInputMode="stateVisible|adjustResize"
在Activity中 声明所需用到的变量以及布局的事件监听,
1 private boolean mBackEnable = false; 2 private boolean mIsBtnBack = false; 3 private int rootBottom = Integer.MIN_VALUE; 4 private OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { 5 @Override 6 public void onGlobalLayout() { 7 Rect r = new Rect(); 8 mSearchLayout.getGlobalVisibleRect(r); 9 // 进入Activity时会布局,第一次调用onGlobalLayout,先记录开始软键盘没有弹出时底部的位置 10 if (rootBottom == Integer.MIN_VALUE) { 11 rootBottom = r.bottom; 12 return; 13 } 14 // adjustResize,软键盘弹出后高度会变小 15 if (r.bottom < rootBottom) { 16 mBackEnable = false; 17 } else { 18 mBackEnable = true; 19 if (mIsBtnBack) { 20 finish(); 21 } 22 } 23 } 24 };
然后在onCreat方法中去注册事件监听
1 mSearchLayout.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
注意:这个mSearchlayout是你整个Activity的布局引用
最后,别忘了,在onDestroy方法中回收掉事件的监听
1 @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 2 @Override 3 protected void onDestroy() { 4 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { 5 mSearchLayout.getViewTreeObserver().removeGlobalOnLayoutListener(mOnGlobalLayoutListener); 6 } else { 7 mSearchLayout.getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener); 8 } 9 super.onDestroy(); 10 }
到这里,android软键盘的监听就结束了。
**什么?你说全屏的时候,没有效果???**
好吧,我也遇到了。。。
我在项目中实现了所有界面的沉浸式效果,本以为Activity设置了adjustResize,OnGlobalLayoutListener仍然能监听软键盘的变化,结果却是屡试不行。。。
无奈,只能求助。查了一些资料,发现这原来是android的一个bug。下面是具体的bug修复代码片段
1 public class AndroidAdjustResizeBugFix { 2 private View mChildOfContent; 3 private int usableHeightPrevious; 4 private int statusBarHeight; 5 private FrameLayout.LayoutParams frameLayoutParams; 6 private Activity mActivity; 7 8 private AndroidAdjustResizeBugFix(Activity activity) { 9 mActivity = activity; 10 FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content); 11 mChildOfContent = content.getChildAt(0); 12 statusBarHeight = getStatusBarHeight(); 13 mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 14 public void onGlobalLayout() { 15 possiblyResizeChildOfContent(); 16 } 17 }); 18 frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams(); 19 } 20 public static void assistActivity(Activity activity) { 21 new AndroidAdjustResizeBugFix(activity); 22 } 23 private void possiblyResizeChildOfContent() { 24 int usableHeightNow = computeUsableHeight(); 25 if (usableHeightNow != usableHeightPrevious) { 26 int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight(); 27 int heightDifference = usableHeightSansKeyboard - usableHeightNow; 28 if (heightDifference > (usableHeightSansKeyboard / 4)) { 29 // keyboard probably just became visible 30 // 如果有高度变化,mChildOfContent.requestLayout()之后界面才会重新测量 31 // 这里就随便让原来的高度减去了1 32 frameLayoutParams.height = usableHeightSansKeyboard - 1; 33 } else { 34 // keyboard probably just became hidden 35 frameLayoutParams.height = usableHeightSansKeyboard; 36 } 37 mChildOfContent.requestLayout(); 38 usableHeightPrevious = usableHeightNow; 39 } 40 } 41 private int computeUsableHeight() { 42 Rect r = new Rect(); 43 mChildOfContent.getWindowVisibleDisplayFrame(r); 44 return r.bottom - r.top + statusBarHeight; 45 } 46 private int getStatusBarHeight() { 47 try { 48 Class<?> c = Class.forName("com.android.internal.R$dimen"); 49 Object obj = c.newInstance(); 50 Field field = c.getField("status_bar_height"); 51 int x = Integer.parseInt(field.get(obj).toString()); 52 int dimensionPixelSize = mActivity.getResources().getDimensionPixelSize(x); 53 return dimensionPixelSize; 54 } catch (Exception e) { 55 e.printStackTrace(); 56 } 57 return 0; 58 } 59 }
把这个类作为一个工具类,添加到项目中,然后,在需要做优化的Activity的onCreate方法中注册activity即可,如:
1 AndroidAdjustResizeBugFix.assistActivity(this);
以上,就是关于监听软键盘弹出和收起的所有内容。
以上是关于完美解决android软键盘监听的主要内容,如果未能解决你的问题,请参考以下文章
android设置软键盘搜索键以及监听搜索键点击时发生两次事件的问题解决