android 軟鍵盤在全屏下的布局計算問題

來源:互聯網
上載者:User

標籤:android   移動   布局   軟鍵盤   IME   

在非全螢幕模式下,將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/19494006import 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)之後調用。


例子源碼


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.