代码来源
public class KeyboardChangeListener implements ViewTreeObserver.OnGlobalLayoutListener { private static final String TAG = "ListenerHandler"; private View mContentView; private int mOriginHeight; private int mPreHeight; private KeyBoardListener mKeyBoardListen; public interface KeyBoardListener { /** * call back * @param isShow true is show else hidden * @param keyboardHeight keyboard height */ void onKeyboardChange(boolean isShow, int keyboardHeight); } public void setKeyBoardListener(KeyBoardListener keyBoardListen) { this.mKeyBoardListen = keyBoardListen; } public KeyboardChangeListener(Activity contextObj) { if (contextObj == null) { Log.i(TAG, "contextObj is null"); return; } mContentView = findContentView(contextObj); if (mContentView != null) { addContentTreeObserver(); } } private View findContentView(Activity contextObj) { return contextObj.findViewById(android.R.id.content); } private void addContentTreeObserver() { mContentView.getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { Rect rect = new Rect(); mContentView.getWindowVisibleDisplayFrame(rect); int currHeight = rect.bottom - rect.top; if (currHeight == 0) { Log.i(TAG, "currHeight is 0"); return; } boolean hasChange = false; if (mPreHeight == 0) { mPreHeight = currHeight; mOriginHeight = currHeight; } else { if (mPreHeight != currHeight) { hasChange = true; mPreHeight = currHeight; } else { hasChange = false; } } if (hasChange) { boolean isShow; int keyboardHeight = 0; if (mOriginHeight == currHeight) { //hidden isShow = false; } else { //show keyboardHeight = mOriginHeight - currHeight; isShow = true; } if (mKeyBoardListen != null) { mKeyBoardListen.onKeyboardChange(isShow, keyboardHeight); } } } public void destroy() { if (mContentView != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mContentView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } } }}
通过GlobalLayoutChangeListener进行监听,如果widonw的可视空间减小了,那么久表示软键盘弹出。如果变大了就表示软键盘收起。
实际上还可以加上一个阈值,比如增大了超过200个像素才当做弹出,这样会更加准确。
使用起来也并不复杂
public class MainActivity extends AppCompatActivity implements KeyboardChangeListener.KeyBoardListener { private static final String TAG = "MainActivity"; private KeyboardChangeListener mKeyboardChangeListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // dosomething while show the keyboard! mKeyboardChangeListener = new KeyboardChangeListener(this); mKeyboardChangeListener.setKeyBoardListener(this); } @Override public void onKeyboardChange(boolean isShow, int keyboardHeight) { Log.d(TAG, "onKeyboardChange() called with: " + "isShow = [" + isShow + "], keyboardHeight = [" + keyboardHeight + "]"); }}
另外还有一个非常重要的条件,就是相应的activity需要设置
android:windowSoftInputMode="adjustResize"
如果当键盘出现的时候屏幕大小不会改变,那么就会无法读取键盘状态。