最近項目需求用到彈窗,但是在彈窗里有EditText,從而引發(fā)系統(tǒng)輸入法覆蓋彈窗的問題,值此記錄下。
網(wǎng)上很多關(guān)于布局或者ScrollView的解決方案,但是木有起作用。最終從這篇博客里得到靈感,貼下鏈接
android 解決輸入法鍵盤遮蓋布局問題 - kobe8 - 博客園。
不過實踐中有個細節(jié)不足,此文做下補充。
/**
* @param root 最外層布局,需要調(diào)整的布局
* @param scrollToView 被鍵盤遮擋的scrollToView,滾動root,使scrollToView在root可視區(qū)域的底部
*/
private void controlKeyboardLayout(final View root, final View scrollToView) {
root.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
//獲取root在窗體的可視區(qū)域
root.getWindowVisibleDisplayFrame(rect);
//獲取root在窗體的不可視區(qū)域高度(被其他View遮擋的區(qū)域高度)
int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom;
//若不可視區(qū)域高度大于100,則鍵盤顯示
if (rootInvisibleHeight > 100) {
int[] location = new int[2];
//獲取scrollToView在窗體的坐標
scrollToView.getLocationInWindow(location);
//計算root滾動高度,使scrollToView在可見區(qū)域的底部
int srollHeight = (location[1] + scrollToView.getHeight()) - rect.bottom;
root.scrollTo(0, srollHeight);
} else {
//鍵盤隱藏
root.scrollTo(0, 0);
}
}
});
}
//獲取root在窗體的可視區(qū)域
root.getWindowVisibleDisplayFrame(rect);
如果root的寬高是match_parent,那獲取的可視區(qū)域不包括頂部狀態(tài)欄和底部的導(dǎo)航欄(有的手機顯示上木有導(dǎo)航欄,但是會有導(dǎo)航欄的高度)的。
可以通過一下代碼拿導(dǎo)航欄高度
/**
*@paramcontext
*@return
*/
public static intgetNavigationBarHeight(Context context) {
Resources resources = context.getResources();
intresourceId = resources.getIdentifier("navigation_bar_height","dimen","android");
intheight = resources.getDimensionPixelSize(resourceId);
returnheight;
}
所以在系統(tǒng)輸入法沒有彈出來的時候,會發(fā)現(xiàn)
//獲取root在窗體的不可視區(qū)域高度(被其他View遮擋的區(qū)域高度)
int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom;
拿到的是144而不是100,從而前文的if條件成立,導(dǎo)致多余的Scroll。其實在初始情況下,rootInvisibleHeight的值就是手機底部導(dǎo)航欄的高度。
所以,判斷輸入法是否彈出的條件是rootInvisibleHeight>NavigationBarHeight,而不是100這個臆想的值。