您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Android中如何獲取軟鍵盤狀態和軟鍵盤高度,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
詳解Android中獲取軟鍵盤狀態和軟鍵盤高度
應用場景
在Android應用中有時會需要獲取軟鍵盤的狀態(即軟鍵盤是顯示還是隱藏)和軟鍵盤的高度。這里列舉了一些可能的應用場景。
場景一
當軟鍵盤顯示時,按下返回鍵應當是收起軟鍵盤,而不是回退到上一個界面,但部分機型在返回鍵處理上有bug,按下返回鍵后,雖然軟鍵盤會自動收起,但不會消費返回事件,導致Activity還會收到這次返回事件,執行回退操作,這時就需要判斷,如果軟鍵盤剛剛由顯示變為隱藏狀態,就不執行回退操作。
場景二
當軟鍵盤彈出后,會將界面底部到中間的一大部分全部擋住,如果用戶要查看、操作被覆蓋的區域,必須先收起軟鍵盤,這會影響用戶交互。所以通常需要在軟鍵盤彈出后,將底部的一些View,例如Button,移到軟鍵盤的上方,方便用戶操作。
API的困境
Android SDK中沒有提供任何API來直接獲取軟鍵盤的狀態和軟鍵盤的高度,網上很多資料說InputMethodManager的isActive()方法可以獲取軟鍵盤狀態,不過實際測試發現,這個方法并沒有什么用,如果它返回false,可以判斷軟鍵盤一定是隱藏的,但如果它返回true,軟鍵盤既可能是顯示的,也可能是隱藏的。所以并不能通過isActive()方法來判斷軟鍵盤究竟是顯示還是隱藏的。要想獲取軟鍵盤的狀態和軟鍵盤的高度,只能通過間接方法實現。
注冊布局變化監聽
在Android中當軟鍵盤由隱藏變為顯示,或由顯示變為隱藏時,會觸發當前布局中View的全局布局變化。通過監聽全局布局的變化就可以得知軟鍵盤的狀態。
Android框架提供了一個ViewTreeObserver類,它是一個View視圖樹的觀察者類。ViewTreeObserver類中定義了一系列的公共接口(public interface)。當一個View attach到一個窗口上時就會創建一個ViewTreeObserver對象,這樣當一個View的視圖樹發生改變時,就會調用該對象的某個方法,將事件通知給每個注冊的監聽者。
OnGlobalLayoutListener是ViewTreeObserver中定義的眾多接口中的一個,它用來監聽一個視圖樹中全局布局的改變或者視圖樹中的某個視圖的可視狀態的改變。當軟鍵盤由隱藏變為顯示,或由顯示變為隱藏時,都會調用當前布局中所有存在的View中的ViewTreeObserver對象的dispatchOnGlobalLayout()方法,此方法中會遍歷所有已注冊的OnGlobalLayoutListener,執行相應的回調方法,將全局布局改變的消息通知給每個注冊的監聽者。
向一個View中的ViewTreeObserver注冊OnGlobalLayoutListener的方法如下。
view.getViewTreeObserver().addOnGlobalLayoutListener(listener);
注冊OnGlobalLayoutListener時有一些需要注意的地方。
注冊的監聽在不使用時需要調用removeOnGlobalLayoutListener或removeGlobalOnLayoutListener來移除監聽,不然可能會導致內存泄露。通常可以在Activity的onCreate()方法中注冊監聽,在onDestory()方法中移除監聽。
并不是只有顯示和隱藏軟鍵盤會觸發OnGlobalLayoutListener中的回調,一個View在繪制完成,或者消失時都會觸發OnGlobalLayoutListener中的回調(由于在onCreate中無法獲取一個View的寬度和高度,很多時候就是通過注冊OnGlobalLayoutListener,在OnGlobalLayoutListener的回調中來獲取一個View的寬度和高度)。
為了在OnGlobalLayoutListener的回調中準確的判斷是否是由于軟鍵盤狀態改變引起的,以及獲取軟鍵盤的高度,還需要另外一個接口。
獲取當前窗口可見的顯示區域大小
在View中提供了一個方法getWindowVisibleDisplayFrame(),此方法會返回該view所附著的窗口的可見區域大小。當軟鍵盤顯示時,窗口的可見區域大小會被壓縮,當軟鍵盤隱藏時,窗口的可見區域大小會還原。不過并不是只有軟鍵盤的顯示和隱藏會影響窗口的可見區域大小,像大多數的平板和部分手機上有一排虛擬按鍵(虛擬的返回鍵,Home鍵等),虛擬按鍵的顯示和隱藏也會引起窗口可見區域的變化。不過好在除了軟鍵盤外,其他操作對窗口可見區域的影響占整個屏幕大小的比例都不是很大,通過設置一個合理的閾值,就可以較準確的判斷出是否是軟鍵盤顯示和隱藏引起的布局變化。
此外,getWindowVisibleDisplayFrame()會返回窗口的可見區域高度,通過和屏幕高度相減,就可以得到軟鍵盤的高度了。
監聽軟鍵盤的狀態變化
在獲取到軟鍵盤的狀態和高度后就可以執行需要的操作了。如重新布局按鈕位置,設置變量,記錄當前軟鍵盤狀態和上次軟鍵盤隱藏時間等。不過如果有多個類需要根據軟鍵盤狀態來執行一些操作,如果每個類中都去這樣做一遍就很麻煩,而且也沒有必要。這時在可以自行定義一個接口,在主Activity中對軟鍵盤狀態變化進行監聽,其他對軟鍵盤狀態感興趣的類,向主Activity中注冊軟鍵盤狀態變化監聽。在主Activity中,當軟鍵盤狀態發生改變時通知監聽者。
完整示例代碼
完整的示例代碼如下。
public interface OnSoftKeyboardStateChangedListener { public void OnSoftKeyboardStateChanged(boolean isKeyBoardShow, int keyboardHeight); } //注冊軟鍵盤狀態變化監聽 public void addSoftKeyboardChangedListener(OnSoftKeyboardStateChangedListener listener) { if (listener != null) { mKeyboardStateListeners.add(listener); } } //取消軟鍵盤狀態變化監聽 public void removeSoftKeyboardChangedListener(OnSoftKeyboardStateChangedListener listener) { if (listener != null) { mKeyboardStateListeners.remove(listener); } } private ArrayList<OnSoftKeyboardStateChangedListener> mKeyboardStateListeners; //軟鍵盤狀態監聽列表 private OnGlobalLayoutListener mLayoutChangeListener; private boolean mIsSoftKeyboardShowing; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); mIsSoftKeyboardShowing = false; mKeyboardStateListeners = new ArrayList<OnSoftKeyboardStateChangedListener>(); mLayoutChangeListener = new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //判斷窗口可見區域大小 Rect r = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(r); //如果屏幕高度和Window可見區域高度差值大于整個屏幕高度的1/3,則表示軟鍵盤顯示中,否則軟鍵盤為隱藏狀態。 int heightDifference = screenHeight - (r.bottom - r.top); boolean isKeyboardShowing = heightDifference > screenHeight/3; //如果之前軟鍵盤狀態為顯示,現在為關閉,或者之前為關閉,現在為顯示,則表示軟鍵盤的狀態發生了改變 if ((mIsSoftKeyboardShowing && !isKeyboardShowing) || (!mIsSoftKeyboardShowing && isKeyboardShowing)) { mIsSoftKeyboardShowing = isKeyboardShowing; for (int i = 0; i < mKeyboardStateListeners.size(); i++) { OnSoftKeyboardStateChangedListener listener = mKeyboardStateListeners.get(i); listener.OnSoftKeyboardStateChanged(mIsSoftKeyboardShowing, heightDifference); } } } }; //注冊布局變化監聽 getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(mLayoutChangeListener); } @SuppressWarnings("deprecation") @SuppressLint("NewApi") @Override protected void onDestroy() { //移除布局變化監聽 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(mLayoutChangeListener); } else { getWindow().getDecorView().getViewTreeObserver().removeGlobalOnLayoutListener(mLayoutChangeListener); } super.onDestroy(); };
其中screenHeight 是屏幕高度,關于屏幕高度的獲取方法,網上有很多,這里就不介紹了。
Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。
關于“Android中如何獲取軟鍵盤狀態和軟鍵盤高度”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。