最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Android中獲取軟鍵盤狀態(tài)和軟鍵盤高度

 更新時間:2017年10月13日 10:26:58   作者:ccpat  
這篇文章主要介紹了詳解Android中獲取軟鍵盤狀態(tài)和軟鍵盤高度的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下

詳解Android中獲取軟鍵盤狀態(tài)和軟鍵盤高度

應(yīng)用場景

在Android應(yīng)用中有時會需要獲取軟鍵盤的狀態(tài)(即軟鍵盤是顯示還是隱藏)和軟鍵盤的高度。這里列舉了一些可能的應(yīng)用場景。

場景一

當(dāng)軟鍵盤顯示時,按下返回鍵應(yīng)當(dāng)是收起軟鍵盤,而不是回退到上一個界面,但部分機(jī)型在返回鍵處理上有bug,按下返回鍵后,雖然軟鍵盤會自動收起,但不會消費(fèi)返回事件,導(dǎo)致Activity還會收到這次返回事件,執(zhí)行回退操作,這時就需要判斷,如果軟鍵盤剛剛由顯示變?yōu)殡[藏狀態(tài),就不執(zhí)行回退操作。

場景二

當(dāng)軟鍵盤彈出后,會將界面底部到中間的一大部分全部擋住,如果用戶要查看、操作被覆蓋的區(qū)域,必須先收起軟鍵盤,這會影響用戶交互。所以通常需要在軟鍵盤彈出后,將底部的一些View,例如Button,移到軟鍵盤的上方,方便用戶操作。

API的困境

Android SDK中沒有提供任何API來直接獲取軟鍵盤的狀態(tài)和軟鍵盤的高度,網(wǎng)上很多資料說InputMethodManager的isActive()方法可以獲取軟鍵盤狀態(tài),不過實際測試發(fā)現(xiàn),這個方法并沒有什么用,如果它返回false,可以判斷軟鍵盤一定是隱藏的,但如果它返回true,軟鍵盤既可能是顯示的,也可能是隱藏的。所以并不能通過isActive()方法來判斷軟鍵盤究竟是顯示還是隱藏的。要想獲取軟鍵盤的狀態(tài)和軟鍵盤的高度,只能通過間接方法實現(xiàn)。

注冊布局變化監(jiān)聽

在Android中當(dāng)軟鍵盤由隱藏變?yōu)轱@示,或由顯示變?yōu)殡[藏時,會觸發(fā)當(dāng)前布局中View的全局布局變化。通過監(jiān)聽全局布局的變化就可以得知軟鍵盤的狀態(tài)。

Android框架提供了一個ViewTreeObserver類,它是一個View視圖樹的觀察者類。ViewTreeObserver類中定義了一系列的公共接口(public interface)。當(dāng)一個View attach到一個窗口上時就會創(chuàng)建一個ViewTreeObserver對象,這樣當(dāng)一個View的視圖樹發(fā)生改變時,就會調(diào)用該對象的某個方法,將事件通知給每個注冊的監(jiān)聽者。

OnGlobalLayoutListener是ViewTreeObserver中定義的眾多接口中的一個,它用來監(jiān)聽一個視圖樹中全局布局的改變或者視圖樹中的某個視圖的可視狀態(tài)的改變。當(dāng)軟鍵盤由隱藏變?yōu)轱@示,或由顯示變?yōu)殡[藏時,都會調(diào)用當(dāng)前布局中所有存在的View中的ViewTreeObserver對象的dispatchOnGlobalLayout()方法,此方法中會遍歷所有已注冊的OnGlobalLayoutListener,執(zhí)行相應(yīng)的回調(diào)方法,將全局布局改變的消息通知給每個注冊的監(jiān)聽者。

向一個View中的ViewTreeObserver注冊O(shè)nGlobalLayoutListener的方法如下。

view.getViewTreeObserver().addOnGlobalLayoutListener(listener);

注冊O(shè)nGlobalLayoutListener時有一些需要注意的地方。

  • 注冊的監(jiān)聽在不使用時需要調(diào)用removeOnGlobalLayoutListener或removeGlobalOnLayoutListener來移除監(jiān)聽,不然可能會導(dǎo)致內(nèi)存泄露。通??梢栽贏ctivity的onCreate()方法中注冊監(jiān)聽,在onDestory()方法中移除監(jiān)聽。
  • 并不是只有顯示和隱藏軟鍵盤會觸發(fā)OnGlobalLayoutListener中的回調(diào),一個View在繪制完成,或者消失時都會觸發(fā)OnGlobalLayoutListener中的回調(diào)(由于在onCreate中無法獲取一個View的寬度和高度,很多時候就是通過注冊O(shè)nGlobalLayoutListener,在OnGlobalLayoutListener的回調(diào)中來獲取一個View的寬度和高度)。

為了在OnGlobalLayoutListener的回調(diào)中準(zhǔn)確的判斷是否是由于軟鍵盤狀態(tài)改變引起的,以及獲取軟鍵盤的高度,還需要另外一個接口。

獲取當(dāng)前窗口可見的顯示區(qū)域大小

在View中提供了一個方法getWindowVisibleDisplayFrame(),此方法會返回該view所附著的窗口的可見區(qū)域大小。當(dāng)軟鍵盤顯示時,窗口的可見區(qū)域大小會被壓縮,當(dāng)軟鍵盤隱藏時,窗口的可見區(qū)域大小會還原。不過并不是只有軟鍵盤的顯示和隱藏會影響窗口的可見區(qū)域大小,像大多數(shù)的平板和部分手機(jī)上有一排虛擬按鍵(虛擬的返回鍵,Home鍵等),虛擬按鍵的顯示和隱藏也會引起窗口可見區(qū)域的變化。不過好在除了軟鍵盤外,其他操作對窗口可見區(qū)域的影響占整個屏幕大小的比例都不是很大,通過設(shè)置一個合理的閾值,就可以較準(zhǔn)確的判斷出是否是軟鍵盤顯示和隱藏引起的布局變化。
此外,getWindowVisibleDisplayFrame()會返回窗口的可見區(qū)域高度,通過和屏幕高度相減,就可以得到軟鍵盤的高度了。

監(jiān)聽軟鍵盤的狀態(tài)變化

在獲取到軟鍵盤的狀態(tài)和高度后就可以執(zhí)行需要的操作了。如重新布局按鈕位置,設(shè)置變量,記錄當(dāng)前軟鍵盤狀態(tài)和上次軟鍵盤隱藏時間等。不過如果有多個類需要根據(jù)軟鍵盤狀態(tài)來執(zhí)行一些操作,如果每個類中都去這樣做一遍就很麻煩,而且也沒有必要。這時在可以自行定義一個接口,在主Activity中對軟鍵盤狀態(tài)變化進(jìn)行監(jiān)聽,其他對軟鍵盤狀態(tài)感興趣的類,向主Activity中注冊軟鍵盤狀態(tài)變化監(jiān)聽。在主Activity中,當(dāng)軟鍵盤狀態(tài)發(fā)生改變時通知監(jiān)聽者。

完整示例代碼

完整的示例代碼如下。

public interface OnSoftKeyboardStateChangedListener {
  public void OnSoftKeyboardStateChanged(boolean isKeyBoardShow, int keyboardHeight);
}

//注冊軟鍵盤狀態(tài)變化監(jiān)聽
public void addSoftKeyboardChangedListener(OnSoftKeyboardStateChangedListener listener) {
  if (listener != null) {
    mKeyboardStateListeners.add(listener);
  }
}
//取消軟鍵盤狀態(tài)變化監(jiān)聽
public void removeSoftKeyboardChangedListener(OnSoftKeyboardStateChangedListener listener) {
  if (listener != null) {
    mKeyboardStateListeners.remove(listener);
  }
}

private ArrayList<OnSoftKeyboardStateChangedListener> mKeyboardStateListeners;   //軟鍵盤狀態(tài)監(jiān)聽列表
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() {
      //判斷窗口可見區(qū)域大小
      Rect r = new Rect();
      getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
      //如果屏幕高度和Window可見區(qū)域高度差值大于整個屏幕高度的1/3,則表示軟鍵盤顯示中,否則軟鍵盤為隱藏狀態(tài)。
      int heightDifference = screenHeight - (r.bottom - r.top);
      boolean isKeyboardShowing = heightDifference > screenHeight/3;

      //如果之前軟鍵盤狀態(tài)為顯示,現(xiàn)在為關(guān)閉,或者之前為關(guān)閉,現(xiàn)在為顯示,則表示軟鍵盤的狀態(tài)發(fā)生了改變
      if ((mIsSoftKeyboardShowing && !isKeyboardShowing) || (!mIsSoftKeyboardShowing && isKeyboardShowing)) {
        mIsSoftKeyboardShowing = isKeyboardShowing;
        for (int i = 0; i < mKeyboardStateListeners.size(); i++) {
          OnSoftKeyboardStateChangedListener listener = mKeyboardStateListeners.get(i);
          listener.OnSoftKeyboardStateChanged(mIsSoftKeyboardShowing, heightDifference);
        }
      }
    }
  };
  //注冊布局變化監(jiān)聽
  getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(mLayoutChangeListener);
}

@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
protected void onDestroy() {
  //移除布局變化監(jiān)聽
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(mLayoutChangeListener);
  } else {
    getWindow().getDecorView().getViewTreeObserver().removeGlobalOnLayoutListener(mLayoutChangeListener);
  }
  super.onDestroy();
};

其中screenHeight 是屏幕高度,關(guān)于屏幕高度的獲取方法,網(wǎng)上有很多,這里就不介紹了。

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Android編程實現(xiàn)的手寫板和涂鴉功能

    Android編程實現(xiàn)的手寫板和涂鴉功能

    這篇文章主要介紹了Android編程實現(xiàn)的手寫板和涂鴉功能,涉及Android界面布局及圖形繪制功能相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • android實現(xiàn)九宮格程序

    android實現(xiàn)九宮格程序

    這篇文章主要為大家詳細(xì)介紹了android實現(xiàn)九宮格程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Flutter Dio二次封裝的實現(xiàn)

    Flutter Dio二次封裝的實現(xiàn)

    這篇文章主要介紹了Flutter Dio二次封裝的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Android中圖片占用內(nèi)存的深入分析

    Android中圖片占用內(nèi)存的深入分析

    我們在日常開發(fā)中應(yīng)該經(jīng)常思考這些問題,圖片占用內(nèi)存跟哪些東西有關(guān)?跟手機(jī)有關(guān)系么?這篇文章主要給大家介紹了關(guān)于Android中圖片占用內(nèi)存的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • Android開發(fā)實現(xiàn)繪制淘寶收益圖折線效果示例

    Android開發(fā)實現(xiàn)繪制淘寶收益圖折線效果示例

    這篇文章主要介紹了Android開發(fā)實現(xiàn)繪制淘寶收益圖折線效果,涉及Android canvas圖形繪制及布局控制相關(guān)操作技巧,需要的朋友可以參考下
    2017-11-11
  • Android使用緩存機(jī)制實現(xiàn)文件下載及異步請求圖片加三級緩存

    Android使用緩存機(jī)制實現(xiàn)文件下載及異步請求圖片加三級緩存

    這篇文章主要介紹了Android使用緩存機(jī)制實現(xiàn)文件下載及異步請求圖片加三級緩存的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Android返回鍵功能的實現(xiàn)方法

    Android返回鍵功能的實現(xiàn)方法

    這篇文章主要介紹了Android返回鍵功能的實現(xiàn)方法,實例分析了Android返回鍵的原理與具體的功能實現(xiàn)代碼,非常具有實用價值,需要的朋友可以參考下
    2015-02-02
  • Android編程自定義扁平化對話框示例

    Android編程自定義扁平化對話框示例

    這篇文章主要介紹了Android編程自定義扁平化對話框,結(jié)合具體實例形式分析了Android自定義扁平化對話框的布局與功能相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • Android自定義圓形View實現(xiàn)小球跟隨手指移動效果

    Android自定義圓形View實現(xiàn)小球跟隨手指移動效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義圓形View實現(xiàn)小球跟隨手指移動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Android OKHttp攔截器和緩存案例詳解

    Android OKHttp攔截器和緩存案例詳解

    OkHttp的攔截器鏈?zhǔn)且粋€有序的攔截器集合,請求和響應(yīng)會依次經(jīng)過每個攔截器,這篇文章主要介紹了Android OKHttp攔截器和緩存案例詳解,感興趣的朋友一起看看吧
    2025-04-04

最新評論

米林县| 和顺县| 靖安县| 伊宁市| 龙井市| 额敏县| 黎城县| 永寿县| 抚松县| 博湖县| 枣庄市| 石家庄市| 藁城市| 富宁县| 丹寨县| 大兴区| 偏关县| 临湘市| 那曲县| 清涧县| 鸡泽县| 新竹市| 嫩江县| 虞城县| 城固县| 江安县| 辽宁省| 黄梅县| 赤水市| 深泽县| 都安| 景泰县| 永平县| 紫阳县| 县级市| 乌鲁木齐市| 鸡东县| 曲沃县| 尤溪县| 蒙阴县| 芒康县|