鍵盤遮擋輸入框bug

今天解決了一個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值爲零。

 

如果大家有想法歡迎給點意見

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章