在非全屏模式下,將activity的windowSoftInputMode的屬性設置爲:adjustResize。同時在View的onSizeChanged(int w, int h, int oldw, int oldh)裏可以得到變化後的尺寸,然後根據前後變化的結果來計算屏幕需要移動的距離。
但是在全屏模式下,即使將activity的windowSoftInputMode的屬性設置爲:adjustResize。在鍵盤顯示時它未將Activity的Screen向上推動,所以你Activity的view的根樹的尺寸是沒有變化的。在這種情況下,你也就無法得知鍵盤的尺寸,對根view的作相應的推移。全屏下的鍵盤無法Resize的問題從2.1就已經存在了,直到現在google還未給予解決。
如果你想了解android 軟鍵盤普通情況下顯示與隱藏的問題,你可以瞭解這篇博客android 軟鍵盤的顯示與隱藏問題的研究,它可以幫助你解決在非全屏下,軟鍵盤的顯示時,你不能很好地控制佈局的問題。
感謝Ricardo提供的輪子,他在stackoverflow找到了解決方案。有人已經封裝好了該類,你只需引用就OK了,我們來看下這個幫助類。
幫助類源碼:
//Workaround to get adjustResize functionality for input methos when the fullscreen mode is on
//found by Ricardo
//taken from http://stackoverflow.com/a/19494006
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
public class AndroidBug5497Workaround {
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
public static void assistActivity (Activity activity) {
new AndroidBug5497Workaround(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private AndroidBug5497Workaround(Activity activity) {
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard/4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}
可以從源碼看到其中的原理。
1.利用viewTreeobserver來監聽View根樹的變化。一旦鍵盤顯示或隱藏都會引起addOnGlobalLayoutListener()方法調用。
2.計算Activtiy可視區域的高度,然後與上次可視區域高度進行比較,若相等,界面出現在變化。
3.如果界面出現變化,計算可視區域高度visibleHeight與Activity根view的高度rootHeight之差heightDifference。
4.如果heightDifference > (rootHeight / 4), 則認爲鍵盤顯示,否則認爲鍵盤隱藏。
5.根據鍵盤變化的狀態,對Activity的contentView進行高度屬性作出改變。
至此,你已經完成了對鍵盤顯示或隱藏對contentView的Resize了。
使用方法
在你的Activity的oncreate()方法裏調用AndroidBug5497Workaround.assistActivity(this);即可。注意:在setContentView(R.layout.xxx)之後調用。