成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Android中如何獲取軟鍵盤(pán)狀態(tài)和軟鍵盤(pán)高度-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)Android中如何獲取軟鍵盤(pán)狀態(tài)和軟鍵盤(pán)高度,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

突泉網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,突泉網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為突泉千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的突泉做網(wǎng)站的公司定做!

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

應(yīng)用場(chǎng)景

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

場(chǎng)景一

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

場(chǎng)景二

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

API的困境

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

注冊(cè)布局變化監(jiān)聽(tīng)

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

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

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

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

view.getViewTreeObserver().addOnGlobalLayoutListener(listener);

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

  • 注冊(cè)的監(jiān)聽(tīng)在不使用時(shí)需要調(diào)用removeOnGlobalLayoutListener或removeGlobalOnLayoutListener來(lái)移除監(jiān)聽(tīng),不然可能會(huì)導(dǎo)致內(nèi)存泄露。通??梢栽贏ctivity的onCreate()方法中注冊(cè)監(jiān)聽(tīng),在onDestory()方法中移除監(jiān)聽(tīng)。

  • 并不是只有顯示和隱藏軟鍵盤(pán)會(huì)觸發(fā)OnGlobalLayoutListener中的回調(diào),一個(gè)View在繪制完成,或者消失時(shí)都會(huì)觸發(fā)OnGlobalLayoutListener中的回調(diào)(由于在onCreate中無(wú)法獲取一個(gè)View的寬度和高度,很多時(shí)候就是通過(guò)注冊(cè)O(shè)nGlobalLayoutListener,在OnGlobalLayoutListener的回調(diào)中來(lái)獲取一個(gè)View的寬度和高度)。

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

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

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

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

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

完整示例代碼

完整的示例代碼如下。

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

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

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

      //如果之前軟鍵盤(pán)狀態(tài)為顯示,現(xiàn)在為關(guān)閉,或者之前為關(guān)閉,現(xiàn)在為顯示,則表示軟鍵盤(pá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);
        }
      }
    }
  };
  //注冊(cè)布局變化監(jiān)聽(tīng)
  getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(mLayoutChangeListener);
}

@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
protected void onDestroy() {
  //移除布局變化監(jiān)聽(tīng)
  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)上有很多,這里就不介紹了。

Android是什么

Android是一種基于Linux內(nèi)核的自由及開(kāi)放源代碼的操作系統(tǒng),主要使用于移動(dòng)設(shè)備,如智能手機(jī)和平板電腦,由美國(guó)Google公司和開(kāi)放手機(jī)聯(lián)盟領(lǐng)導(dǎo)及開(kāi)發(fā)。

關(guān)于“Android中如何獲取軟鍵盤(pán)狀態(tài)和軟鍵盤(pán)高度”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

標(biāo)題名稱(chēng):Android中如何獲取軟鍵盤(pán)狀態(tài)和軟鍵盤(pán)高度-創(chuàng)新互聯(lián)
瀏覽路徑:http://jinyejixie.com/article42/dsejec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT網(wǎng)站策劃、域名注冊(cè)、品牌網(wǎng)站制作、全網(wǎng)營(yíng)銷(xiāo)推廣關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
池州市| 遂昌县| 盐亭县| 荆门市| 英德市| 津南区| 醴陵市| 乌拉特前旗| 鄢陵县| 陵川县| 拜城县| 古蔺县| 深圳市| 金乡县| 缙云县| 八宿县| 盘山县| 墨玉县| 延安市| 苍南县| 电白县| 浪卡子县| 凤山县| 三江| 永泰县| 通江县| 新绛县| 兴城市| 新野县| 宜章县| 崇州市| 赫章县| 罗山县| 武穴市| 赤壁市| 和平县| 阳谷县| 金坛市| 绥棱县| 久治县| 子洲县|