代码来源https://github.com/yescpu/KeyboardChangeListener
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"
如果当键盘出现的时候屏幕大小不会改变,那么就会无法读取键盘状态。