場景1
問題描述
常規(guī)的泉坐,當(dāng)點擊EditText
輸入框時两入,軟鍵盤彈出轨奄,但鍵盤會遮擋EditText
顯示孟害。
解決方案
AndroidManifest
文件中,Activity新增配置android:windowSoftInputMode
挪拟,設(shè)置值為adjustPan
或adjustResize
挨务,如下:
<activity
android:name="xxx"
android:windowSoftInputMode="adjustPan" />
adjustPan和 adjustResize的區(qū)別
-
adjustPan
配置該參數(shù),整個界面會向上平移玉组,顯示輸入框谎柄,但不改變界面的布局。 -
adjustResize
配置該參數(shù)惯雳,系統(tǒng)會重新計算除去軟鍵盤后的界面尺寸朝巫,用更少的界面區(qū)域顯示內(nèi)容,輸入框也在其中石景。
場景2
問題描述
混合開發(fā)中劈猿,應(yīng)用在非全屏模式下,WebView
加載網(wǎng)頁潮孽,點擊輸入框揪荣,軟鍵盤遮擋問題。
解決方案
操作方法同上往史,但是只支持設(shè)置值為adjustResize
仗颈,設(shè)置 adjustPan
無效。
場景3
問題描述
- 混合開發(fā)中椎例,應(yīng)用在全屏模式下(Application或activity使用Fullscreen主題挨决、沉浸式狀態(tài)欄、
Immersive Mode
等)订歪,WebView加載網(wǎng)頁脖祈,點擊輸入框,軟鍵盤遮擋問題刷晋。 -
android:windowSoftInputMode
設(shè)置值為adjustPan
或adjustResize
均無效撒犀。 - 這是系統(tǒng)級別的一個坑福压。
解決方案
方案1
當(dāng)一個Activity
中包含WebView
控件時掏秩,盡量避免使用全景模式或舞。(當(dāng)然這個方法治標(biāo)不治本)
方案2
stackflow
上有個大牛提供了解決方案。(stackflow地址)
具體代碼如下蒙幻,
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
/**
* 修復(fù)WebView全屏模式下映凳,軟鍵盤遮擋問題
*/
public final class AndroidBug5497Workaround {
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private int contentHeight;
private boolean isFirst = true;
private int statusBarHeight;
public static void assistActivity(Activity activity) {
new AndroidBug5497Workaround(activity);
}
private AndroidBug5497Workaround(Activity activity) {
//獲取狀態(tài)欄的高度
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
//界面出現(xiàn)變動都會調(diào)用這個監(jiān)聽事件
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (isFirst) {
contentHeight = mChildOfContent.getHeight();//兼容華為等機型
isFirst = false;
}
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
/**
* 重新調(diào)整布局的高度
*/
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
//當(dāng)前可見高度和上一次可見高度不一致 布局變動
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
} else {
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
}
} else {
frameLayoutParams.height = contentHeight;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
/**
* 計算mChildOfContent可見高度
*
* @return
*/
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}
- 將該類新增到項目中,并在對應(yīng)
Activity
的onCreate()
方法中調(diào)用即可邮破。
AndroidBug5497Workaround.assistActivity(this);
AndroidBug5497Workaround
類解析:
通過
findViewById(android.R.id.content)
獲取Activity界面開發(fā)者可控區(qū)域的根View诈豌。(全屏模式下,即為全部屏幕區(qū)域抒和,非全屏模式下為除狀態(tài)欄外區(qū)域)mChildOfContent = content.getChildAt(0);
矫渔,獲取Activity
布局的View
(即通過setContentView()
設(shè)置的View
)。View.getViewTreeObserver()
獲取一個專門監(jiān)聽當(dāng)前View樹變化的觀察者對象摧莽。由于軟鍵盤的彈出庙洼,會使View樹的全局布局(GlobalLayout)發(fā)生變化,所以給當(dāng)前View樹變化的觀察者對象綁定監(jiān)聽
addOnGlobalLayoutListener
镊辕。一旦觸發(fā)
addOnGlobalLayoutListener
監(jiān)聽油够,主要則是調(diào)用possiblyResizeChildOfContent()
方法,重置界面變化后可用區(qū)域征懈。possiblyResizeChildOfContent()
方法中石咬,heightDifference > (usableHeightSansKeyboard / 4)
這個判斷只有界面的高度變化超過1/4,才重置高度卖哎,確保響應(yīng)軟鍵盤的彈出鬼悠,排除其他界面變化情況,computeUsableHeight()
則是計算除去鍵盤后重新調(diào)整布局的可用高度亏娜。
軟鍵盤遮擋界面問題總結(jié)
Android輸入框軟鍵盤遮擋問題焕窝,通常有以下三種情況:
在無WebView的界面下:
按需求配置android:windowSoftInputMode
,為adjustPan
或adjustResize
照藻。有WebView的界面下:
非全屏模式:
配置android:windowSoftInputMode
為adjustResize
袜啃。
全屏模式:
項目新增一個AndroidBug5497Workaround
類,完美解決幸缕。