android軟鍵盤與沉浸式的沖突

實例分析下windowSoftInputMode 里面adjustPan和adjustResize的作用,以及在沉浸式樣式下的解決方案
windowSoftInputMode

頁面布局

在沒有設(shè)置scrollview的布局下

"adjustResize"
該 Activity主窗口總是被調(diào)整屏幕的大小以便留出軟鍵盤的空間憎蛤。


adjustResize 界面布局不會動疾牲,鍵盤會擋住輸入框

"adjustPan"
該 Activity主窗口并不調(diào)整屏幕的大小以便留出軟鍵盤的空間园爷。相反吨枉,當(dāng)前窗口的內(nèi)容將自動移動以便當(dāng)前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內(nèi)容的部分。這個通常是不期望比調(diào)整大小怕敬,因為用戶可能關(guān)閉軟鍵盤以便獲得與被覆蓋內(nèi)容的交互操作咖为。

adjustPan輸入框獲得焦點的時候會被鍵盤上移秕狰,不遮擋

在設(shè)置scrollview的布局下
adjustPan 鍵盤不會遮擋輸入框,在原來布局不超過一屏的情況下不能滑動躁染,超過之后只能滑動少許鸣哀,這個原因有待分析。
adjustResize可以通過滑動scrollview布局移出輸入框
總結(jié):
adjustPan類似于鍵盤底部增加一塊鍵盤布局
adjustResize類似于鍵盤覆蓋在界面上面

使用沉浸式樣式時
adjustPan 界面上移軟鍵盤不遮擋輸入框吞彤,但是上面的布局會遮擋狀態(tài)欄

663178288014871941.jpg

adjustResize鍵盤會遮擋輸入框我衬,且不管是否用scrollview布局都不能滑動

解決方案有兩種

第一種是谷歌提的AndroidBug5497Workaround,適配小米,華為,三星時需要修改代碼饰恕,原本的方法在這些手機上會出現(xiàn)高度計算不準(zhǔn)確的情況挠羔,修改后代碼如下

public class AndroidBug5497Workaround {
    public static void assistActivity(Activity activity) {
        new AndroidBug5497Workaround(activity);
    }
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private int contentHeight;
    private   boolean isfirst = true;
    private Activity activity;
    private  int statusBarHeight;

    private AndroidBug5497Workaround(Activity activity) {
        //獲取狀態(tài)欄的高度
        int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
        statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
        this.activity = activity;
        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 usableHeightSansKeyboard2 = mChildOfContent.getHeight();//兼容華為等機型
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard / 4)) {
                // keyboard probably just became visible
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                    //frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                    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);
    }
}

第二種 解決方案 自定義LinearLayout,relativityLayout

ResizeRelativityLayout

public class ResizeLinearLayout extends LinearLayout {

    private int[] mInsets = new int[4];

    public ResizeLinearLayout(Context context) {
        super(context);
    }

    public ResizeLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ResizeLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ResizeLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected final boolean fitSystemWindows(Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason,
            // if the bottom inset is modified, window resizing stops working.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }

    @Override
    public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            mInsets[0] = insets.getSystemWindowInsetLeft();
            mInsets[1] = insets.getSystemWindowInsetTop();
            mInsets[2] = insets.getSystemWindowInsetRight();
            return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                    insets.getSystemWindowInsetBottom()));
        } else {
            return insets;
        }
    }

}

ResizeLinearLayout

public class ResizeLinearLayout extends LinearLayout {

    private int[] mInsets = new int[4];

    public ResizeLinearLayout(Context context) {
        super(context);
    }

    public ResizeLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ResizeLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ResizeLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected final boolean fitSystemWindows(Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason,
            // if the bottom inset is modified, window resizing stops working.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }

    @Override
    public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            mInsets[0] = insets.getSystemWindowInsetLeft();
            mInsets[1] = insets.getSystemWindowInsetTop();
            mInsets[2] = insets.getSystemWindowInsetRight();
            return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                    insets.getSystemWindowInsetBottom()));
        } else {
            return insets;
        }
    }

}

使用方法:在設(shè)置了布局根部使用此控件并且加上android:fitsSystemWindows="true"

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市埋嵌,隨后出現(xiàn)的幾起案子破加,更是在濱河造成了極大的恐慌,老刑警劉巖雹嗦,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件范舀,死亡現(xiàn)場離奇詭異,居然都是意外死亡了罪,警方通過查閱死者的電腦和手機锭环,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泊藕,“玉大人田藐,你說我怎么就攤上這事≈ㄆ撸” “怎么了汽久?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長踊餐。 經(jīng)常有香客問我景醇,道長,這世上最難降的妖魔是什么吝岭? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任三痰,我火速辦了婚禮,結(jié)果婚禮上窜管,老公的妹妹穿的比我還像新娘散劫。我一直安慰自己,他們只是感情好幕帆,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布获搏。 她就那樣靜靜地躺著,像睡著了一般失乾。 火紅的嫁衣襯著肌膚如雪常熙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天碱茁,我揣著相機與錄音裸卫,去河邊找鬼。 笑死纽竣,一個胖子當(dāng)著我的面吹牛墓贿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜓氨,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聋袋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了语盈?” 一聲冷哼從身側(cè)響起舱馅,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刀荒,沒想到半個月后代嗤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡缠借,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年干毅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泼返。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡硝逢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渠鸽,我是刑警寧澤叫乌,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站徽缚,受9級特大地震影響憨奸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凿试,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一排宰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧那婉,春花似錦板甘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痕寓,卻和暖如春傲醉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背呻率。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工硬毕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人礼仗。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓吐咳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親元践。 傳聞我的和親對象是個殘疾皇子韭脊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容