记 Android 部分布局忽然无法显示
总结:这是一个一开始方向错误的问题
某次,APK在测试手机上正常使用,故换了个荣耀X20的设备,想着兼容性应该没有问题,
结果,忽然发现A页面,一个底部布局无法显示,其它页面这个布局可以显示(使用的include),
以为出现了什么奇葩的bug
查找许久,修改测试调整
后发现,原来是A页面初始化时,添加了一个隐藏软键盘的代码,如下
import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.view.View; import android.view.ViewTreeObserver; import android.view.inputmethod.InputMethodManager; import java.util.LinkedList; import java.util.List; public class SoftKeyboardStateHelper implements ViewTreeObserver.OnGlobalLayoutListener { public interface SoftKeyboardStateListener { void onSoftKeyboardOpened(int keyboardHeightInPx); void onSoftKeyboardClosed(); } private final Listlisteners = new LinkedList (); private final View activityRootView; private int lastSoftKeyboardHeightInPx; private boolean isSoftKeyboardOpened; public SoftKeyboardStateHelper(View activityRootView) { this(activityRootView, false); } public SoftKeyboardStateHelper(View activityRootView, boolean isSoftKeyboardOpened) { this.activityRootView = activityRootView; this.isSoftKeyboardOpened = isSoftKeyboardOpened; activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { final Rect r = new Rect(); //r will be populated with the coordinates of your view that area still visible. activityRootView.getWindowVisibleDisplayFrame(r); final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top); if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard... isSoftKeyboardOpened = true; notifyOnSoftKeyboardOpened(heightDiff); } else if (isSoftKeyboardOpened && heightDiff < 100) { isSoftKeyboardOpened = false; notifyOnSoftKeyboardClosed(); } } public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) { this.isSoftKeyboardOpened = isSoftKeyboardOpened; } public boolean isSoftKeyboardOpened() { return isSoftKeyboardOpened; } /** * Default value is zero (0) * @return last saved keyboard height in px */ public int getLastSoftKeyboardHeightInPx() { return lastSoftKeyboardHeightInPx; } public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) { listeners.add(listener); } public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) { listeners.remove(listener); } private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) { this.lastSoftKeyboardHeightInPx = keyboardHeightInPx; for (SoftKeyboardStateListener listener : listeners) { if (listener != null) { listener.onSoftKeyboardOpened(keyboardHeightInPx); } } } private void notifyOnSoftKeyboardClosed() { for (SoftKeyboardStateListener listener : listeners) { if (listener != null) { listener.onSoftKeyboardClosed(); } } } /** * 判断软键盘是否弹出 */ public static boolean isSHowKeyboard(Context context, View v) { InputMethodManager imm = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE); if (imm.hideSoftInputFromWindow(v.getWindowToken(), 0)) { imm.showSoftInput(v, 0); return true; //软键盘已弹出 } else { return false; //软键盘未弹出 } } }
public static void setBottomBySoftKeyBoard(Activity activity, int root, View bottom) { final SoftKeyboardStateHelper softKeyboardStateHelper = new SoftKeyboardStateHelper(activity.findViewById(root)); softKeyboardStateHelper.addSoftKeyboardStateListener(new SoftKeyboardStateHelper.SoftKeyboardStateListener() { @Override public void onSoftKeyboardOpened(int keyboardHeightInPx) { bottom.setVisibility(View.GONE); } @Override public void onSoftKeyboardClosed() { bottom.setVisibility(View.VISIBLE); } }); } }
后来发现这种写法,部分版本手机,如果没有开启软键盘的情况下,会将底部布局隐藏
后来修改为如下写法,此方法为标准写法,理论上应该兼容大部分手机
((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
但是后来,低版本的手机没有什么问题,部分高版本手机,会直接闪退
再后来,添加了判断,如果有软键盘,再隐藏,
if (SoftKeyboardStateHelper.isSHowKeyboard(activity, v)) { ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); }
最后修复了这个奇葩的问题