监听接口 OnKeyboardListener.java
public interface OnKeyboardListener {
void onKeyboardHidden();
void onKeyboardShow(int keyboardHeight);
}
KeyBoardUtil.java
public class KeyBoardUtil {
private final static String TAG = "KeyBoardUtil";
public PopupWindow popupWindow;
public static void showSoftInput(EditText edit) {
edit.setFocusable(true);
edit.setFocusableInTouchMode(true);
edit.requestFocus();
InputMethodManager imm = (InputMethodManager) edit.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, 0);
edit.setSelection(edit.length());
}
public static void hideSoftInput(EditText edit) {
InputMethodManager imm = (InputMethodManager) edit.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
}
private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener;
public void observerKeyboard(Activity activity, OnKeyboardListener keyboardListener) {
View rootView = new View(activity);
popupWindow = new PopupWindow(activity);
try {
rootView.setLayoutParams(new ViewGroup.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT));
popupWindow.setContentView(rootView);
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.setBackgroundDrawable(new ColorDrawable(0));
popupWindow.setTouchable(false);
popupWindow.showAtLocation(activity.getWindow().getDecorView(), Gravity.NO_GRAVITY, 0, 0);
} catch (WindowManager.BadTokenException e) {
Log.d(TAG, "observerKeyboard: " , e);
}
if (onGlobalLayoutListener == null) {
onGlobalLayoutListener = getGlobalObserver(rootView, keyboardListener);
}
rootView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
private ViewTreeObserver.OnGlobalLayoutListener getGlobalObserver(View rootView, OnKeyboardListener keyboardListener) {
HeightWrapper wrapper = new HeightWrapper();
Rect rootRect = new Rect();
Context context = rootView.getContext();
((Activity)context).getWindow().getDecorView().getWindowVisibleDisplayFrame(rootRect);
return () -> {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int height = r.height();
if (wrapper.getHeight() == 0) {
wrapper.setHeight(height);
} else {
if (wrapper.getHeight() != height){
Log.i(TAG,"keyboard wrapper height = "+wrapper.getHeight() + "heigth = "+height);
int diff = wrapper.getHeight() - height;
if (diff < -200 && rootRect.bottom == r.bottom) {
keyboardListener.onKeyboardHidden();
}else {
keyboardListener.onKeyboardShow(ScreenUtils.getScreenRealHeight() - r.bottom);
}
wrapper.setHeight(height);
}
}
};
}
public void clearObserver() {
onGlobalLayoutListener = null;
if (popupWindow != null) {
popupWindow.dismiss();
popupWindow.getContentView().getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
popupWindow = null;
}
static class HeightWrapper {
int height = 0;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
}
在activity 中初始化完UI以后,添加如下代码:
view.viewTreeObserver.addOnGlobalLayoutListener {
if (mKeyBoardUtil == null) {
mKeyBoardUtil = KeyBoardUtil()
mKeyBoardUtil?.observerKeyboard(
requireActivity(),
object : KeyBoardUtil.OnKeyboardListener {
override fun onKeyboardHidden() {
Log.i(TAG, "onKeyboardHidden")
}
override fun onKeyboardShow(keyboardHeight: Int) {
Log.i(TAG, "onKeyboardShow")
}
})
}
}
在activity ondestory中调用:
mKeyBoardUtil?.clearObserver()