今天解決了一個bug,虛擬鍵盤遮擋輸入框。
解決這類問題有多種做法,但是也針對不同的項目情況做法也不同
出現的問題像在底部的輸入框,當鍵盤彈出後輸入框被遮住
解決思路有幾種,需要有幾點需要注意,稍後做一下解釋,也是參考了好多網絡資料再此表示感謝
1.一種時常見的簡單直接在manifest中設置windowSoftInputModel="adjustPan|stateHidden"
這種在佈局中用Scorllview套住即可。當然根據不通的主題設置有各種不同的注意點,網上有說ScrollView中fillViewPort=true的,有說fitSystemWindow=true的情況。下面是我的情況使用的。綜合給大家些意見。
2.一種是,整個activity頂起,達到不被遮住的目的
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);// 全屏模式下: return r.bottom
}
}
這種是把整個activity上移達到不被遮擋,看代碼知道是把activity的setContentView做處理
這種情況很方便,但是我改的別人bug使用無效,情況是項目主題設置了背景透明,這裏這種方法有bug就是,當虛擬鍵盤彈出後,關閉鍵盤這時就會出現背景透明。如果沒有設置主題背景透明這種情況是沒有問題的也挺方便。
3.第二種就設置佈局的padding值代碼如下,當鍵盤談起時把底部墊高,也算適合我這種情況,但是如果又在activity中設置全屏模式,我提到的所有情況都無效。
public class KeyboardPatch {
private Activity activity;
private View decorView;
private View contentView;
/**
* 構造函數
* @param act 需要解決bug的activity
* @param contentView 界面容器,activity中一般是R.id.content,也可能是Fragment的容器,根據個人需要傳遞
* */
public KeyboardPatch(Activity act, View contentView)
{
this.activity = act;
this.decorView = act.getWindow().getDecorView();
this.contentView = contentView;
}
/**
* 監聽layout變化
* */
public void enable()
{
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
if (Build.VERSION.SDK_INT >= 19)
{
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
/**
* 取消監聽
* */
public void disable()
{
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
if (Build.VERSION.SDK_INT >= 19)
{
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
Rect r = new Rect();
decorView.getWindowVisibleDisplayFrame(r);
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int diff = height - r.bottom;
if (diff != 0)
{
if (contentView.getPaddingBottom() != diff)
{
contentView.setPadding(0, 0, 0, diff);
}
}
else
{
if (contentView.getPaddingBottom() != 0)
{
contentView.setPadding(0, 0, 0, 0);
}
}
}
};
}
這種可以根據你的情況設置contentview,看代碼就是,虛擬鍵盤彈出時設置padding值墊高,關閉時padding值爲零。
如果大家有想法歡迎給點意見