最近要做一个全局输入框,只能通过onGlobalLayout调整适应布局顶起键盘给予正确的高度,遇到国产虚拟按键可算是天坑。
问题在于很多只搜到了是否存在虚拟按键,但是随着全面屏手势等出现,这个虚拟按键是可以动态显示隐藏的,当隐藏的时候这个判断方法依然为true,如果大家知道除了小米之外的官方判断 欢迎补充
下面我的处理方法。
//diff为负数的时候说明减去虚拟按键的高度 变为了负数侧面证明虚拟按键已经隐藏
public static boolean isAbNoHasNavigationBar = false;
public static void addGlobalLayoutListener(final Activity activity) {
final View decorView = activity.getWindow().getDecorView();
final View contentView = activity.findViewById(Window.ID_ANDROID_CONTENT);
final int navigationBarHeight = RomUtils.getNavigationBarHeight(activity);
//小米是否显示了虚拟按键
final boolean isXiaoMIhas = !xiaomiNavigationGestureEnabled(activity);
ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
decorView.getWindowVisibleDisplayFrame(r);
int height = getTrueHeight(decorView.getContext());
int diff = height - r.bottom;
//最坑的地方在于很多方法只能判断是否有虚拟按键这个功能,但是无法判断是否启用
if (RomUtils.checkIsMiuiRom()) {
if (isXiaoMIhas) {
//显示虚拟按键
diff = diff - navigationBarHeight;
}
} else {
if (isAbNoHasNavigationBar){
//此时在有虚拟键的情况下关闭了虚拟键
}else {
if(RomUtils.hasSoftKeys(activity.getWindow().getWindowManager()){
diff = diff - navigationBarHeight;
}
}
}
Log.i("rex", "diff:" + diff);
if (diff < 0) {
isAbNoHasNavigationBar = true;
}
if (diff > 0) {
if (contentView.getPaddingBottom() != diff) {
contentView.setPadding(0, 0, 0, diff);
}
} else {
if (contentView.getPaddingBottom() != 0) {
contentView.setPadding(0, 0, 0, 0);
}
}
}
};
decorView.getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
private static final String XIAOMI_FULLSCREEN_GESTURE = "force_fsg_nav_bar";
public static boolean xiaomiNavigationGestureEnabled(Context context) {
int val = Settings.Global.getInt(context.getContentResolver(), XIAOMI_FULLSCREEN_GESTURE, 0);
return val != 0;
}