自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android 軟鍵盤的顯示和隱藏,這樣操作就對了

企業(yè)動態(tài)
想要操作軟鍵盤,需要使用到 InputMethodManager ,它是一個系統(tǒng)服務(wù),可以使用 Context.getSystemService() 獲取到它。而很多關(guān)鍵的邏輯代碼,都是在 InputMethodManagerService 中實(shí)現(xiàn)的。

[[212224]]

 一、前言

如果有需要用到輸入的地方,通常會有需要自動彈出或者收起軟鍵盤的需求。開篇明義,本文會講講彈出和收起軟鍵盤的一些細(xì)節(jié),最終還會從源碼進(jìn)行分析。

想要操作軟鍵盤,需要使用到 InputMethodManager ,它是一個系統(tǒng)服務(wù),可以使用 Context.getSystemService() 獲取到它。而很多關(guān)鍵的邏輯代碼,都是在 InputMethodManagerService 中實(shí)現(xiàn)的。

特別說明:本文的所有分析的源碼,都是基于 Android 26 的源碼。

二、操作軟鍵盤

2.1 InputMethodManager

前面提到,想要操作軟鍵盤,需要使用 InputMethodManager ,它是一個系統(tǒng)服務(wù),想要獲取它,可以使用 getSystemService() ,獲取到它。

畢竟是系統(tǒng)服務(wù),使用的時候?yàn)榱税踩?,還是要判空,避免空指針。

2.2 顯示軟鍵盤

在 InputMethodManager 中,有兩個方法 showSoftInput() 和 showSoftInputFromInputMethod() ,而實(shí)際上,只有 showSoftInput() 是有效的。

它有兩個重載方法,而通常我們會使用它的兩個參數(shù)的方法。

這里我們只需要傳遞兩個參數(shù)。它首先需要一個 View ,使用軟鍵盤就是為了輸入,而輸入就需要有接收輸入內(nèi)容的 View ,這里接收輸入的 View ,***是一個 EditText(但這不是必須的)。

而第二個參數(shù) flags 就是個標(biāo)志位,從上面截圖的方法簽名上的文檔上可以看到,它接收 0 或者 SHOW_INPYT_IMPLICIT 兩個參數(shù),但是實(shí)際上,它有第三個參數(shù),另外一個是 SHOW_FORCED。

可以看到 1、2 都是有特殊含義的,實(shí)際上它們并不影響顯示,只是在隱藏的時候,會有一些限制,這些后面看源碼的時候再說,一般沒有特別需要的話,我們直接傳遞 0 就好了。

現(xiàn)在,簡單總結(jié)一下調(diào)用 showSoftInput() 會生效的關(guān)鍵點(diǎn):

1、***個參數(shù),***是 EditText 或者它的子類。

考慮到軟鍵盤就是為了輸入,EditText 就是一個接收輸入的控件。而這不是絕對的,如果不是一個 EditText ,就必須要求這個 View 有兩個屬性,分別是:android:focusable="true" 和android:focusableInTouchMode="true"。

2、***個參數(shù),必須是可獲取焦點(diǎn)的,并且當(dāng)前已經(jīng)獲取到焦點(diǎn)。

EditText 默認(rèn)是允許獲取焦點(diǎn)的,但是假如布局中,存在多個可獲取焦點(diǎn)的控件,就需要提前讓我們傳遞進(jìn)去的 View 獲取到焦點(diǎn)。獲取焦點(diǎn)可以使用 requestFocus() 方法。

3、布局必須加載完成。

在 onCreate() 中,如果立即調(diào)用 showSoftInput() 是不會生效的。想要在頁面一啟動的時候就彈出鍵盤,可以在 Activity 上,設(shè)置 android:windowSoftInputMode 屬性來完成,或者做一個延遲加載,View.postDelayed() 也是一個解決方案。

所以最終,完整的顯示軟鍵盤的代碼就如下所示了。

2.3 隱藏軟鍵盤

雖然 showSoftInput() 方法是有效的,但是想要隱藏軟鍵盤,就沒有提供對應(yīng)的 hideSoftInput() 方法,但是卻有一個 hideSoftInputFromWindow() 方法,可以用來隱藏軟鍵盤。

先來看看這個方法的簽名,它同樣有兩個方法可以調(diào)用。

它接收兩個參數(shù),***個參數(shù)是一個 IBinder ,可以直接傳遞一個 View.getWindowToken() 的 windowToken 對象就可以了。而第二個參數(shù),就是隱藏軟鍵盤的標(biāo)志位,如果沒有特殊要求的話,直接傳遞 0 就好了。

注意這里雖然原則上需要傳遞一個之前彈出鍵盤傳遞的時候,傳遞的 View 的 windowToken ,但是實(shí)際情況是你只需要傳遞一個存在于當(dāng)前布局 ViewTree 中,隨意一個 View 的 windowToken 就可以了。

最終隱藏軟件的代碼就是這樣的。

2.4 切換鍵盤的彈出和隱藏

在 InputMethodManager 中,還提供了一個 toggleSoftInput() 方法,如同它的名字一樣,它可以讓軟鍵盤在顯示和隱藏之間切換。

該方法,接收兩個 flags ,分別是控制 show 和 hide 時候的標(biāo)識,它們的含義和前面介紹的 showSoftInput() 和 hideSoftInputFromWindow() 一致,所以沒有特殊要求,直接傳遞 0 就好了。

toggleSoftInput() 方法不要求傳遞一個 View 或者 windowToken,所以它并沒有 showSoftInput() 中的一些限制,但是依然還有需要在布局繪制完成之后調(diào)用才會有效果。

雖然這個方法,限制很少,但是我們基本上不會使用它。主要原因在于,它是一個開關(guān)的方法,會根據(jù)當(dāng)前的狀態(tài)做相反的操作。這就導(dǎo)致很多時候,我們在代碼中,無法直接根據(jù) InputMethodManager 提供的方法判斷當(dāng)前軟鍵盤的顯示狀態(tài),這樣也就無法確定調(diào)用它的時候的效果了。

三、源碼分析

3.1 flag 的細(xì)節(jié)

前面的一些方法,都需要傳遞一個 flag 值,文檔中描述的并不詳細(xì),我們就從源碼的角度,來分析一下這些 flag 的含義。

先來看看 showSoftInput() 方法。

它最終會調(diào)用 mService.showSoftInput() 方法,最終的源碼,就需要查看 InputMethodManagerService 中的代碼了。而 showSoftInput() 方法,最終會調(diào)用 showCurrentInputLocked()。

這個方法的代碼很長,我們只關(guān)心和 flag 相關(guān)的代碼。

可以看到,flag 會影響兩個字段,mShowExplicitlyRequested 和 mShowForced,而 SHOW_FORCED 會更強(qiáng)勢一點(diǎn)。

hideSoftInputFromWindow() 方法,最終也會調(diào)用 InputMethodManagerService 中的 hideCurrentInputLocked() 方法。

從 DEBUG == true 會輸出的 Log 中,已經(jīng)可以看到含義了。這里會根據(jù)顯示和隱藏傳遞的兩個 flag 來進(jìn)行比對,也就是說,如果 flag 使用不正確,可能導(dǎo)致這里直接返回 false ,從而無法隱藏軟鍵盤,這些細(xì)節(jié)對照代碼就清晰了,就不在文章里屢這些細(xì)節(jié)了。

所以這就是為什么前面提到,如果沒有特殊要求,直接傳遞 0 就好了,可以規(guī)避這個限制。

3.2 如何判斷軟鍵盤是否彈出

既然 toggleSoftInput() 可以根據(jù)當(dāng)前軟鍵盤的狀態(tài),進(jìn)行不同的操作,那么肯定是有辦法確定當(dāng)前軟鍵盤的狀態(tài)的。

那我們繼續(xù)追蹤 toggleSoftInput() 的方法源碼。

該方法,最終會調(diào)用到 InputMethodService 的 onToggleSoftInput() 方法。

在這個方法中,是根據(jù) isInputViewShow() 方法來判定當(dāng)前軟鍵盤是否處于顯示彈出的狀態(tài)。但是我們并沒有辦法,直接和 InputMethodService 進(jìn)行交互,我們也就沒辦法直接拿到當(dāng)前鍵盤是否顯示。

如果想要監(jiān)聽鍵盤的彈出和收起,可以使用 ViewTreeObserver.OnGlobalLayoutListener 這個監(jiān)聽,來監(jiān)聽布局的調(diào)整,從而判斷出鍵盤的彈出和隱藏。這些細(xì)節(jié)有時間再聊。

四、KeyboardUtils

既然已經(jīng)清楚了軟鍵盤的收起和彈出的方法細(xì)節(jié),那我們來寫一個幫助類,來解決這個問題。讓你們拿到就可用。

這里提供一下 Java 版和 Kotlin 版。

4.1 Java 版

  1. public class KeyboardUtils { 
  2.    public static void showKeyboard(View view) { 
  3.        InputMethodManager imm = (InputMethodManager) view.getContext() 
  4.                .getSystemService(Context.INPUT_METHOD_SERVICE); 
  5.        if (imm != null) { 
  6.            view.requestFocus(); 
  7.            imm.showSoftInput(view, 0); 
  8.        } 
  9.    } 
  10.    public static void hideKeyboard(View view){ 
  11.        InputMethodManager imm = (InputMethodManager) view.getContext() 
  12.                .getSystemService(Context.INPUT_METHOD_SERVICE); 
  13.        if (imm != null) { 
  14.            imm.hideSoftInputFromWindow(view.getWindowToken(),0); 
  15.        } 
  16.    } 
  17.    public static void  toggleSoftInput(View view){ 
  18.        InputMethodManager imm = (InputMethodManager) view.getContext() 
  19.                .getSystemService(Context.INPUT_METHOD_SERVICE); 
  20.        if (imm != null) { 
  21.            imm.toggleSoftInput(0,0); 
  22.        } 
  23.    } 

4.2 Kotlin 版

  1. object KeyboardktUtils{ 
  2.    fun showKeyboard(viewView) { 
  3.        val imm = view.context 
  4.                .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 
  5.        if (imm != null) { 
  6.            view.requestFocus() 
  7.            imm.showSoftInput(view, 0) 
  8.        } 
  9.    } 
  10.    fun hideKeyboard(viewView) { 
  11.        val imm = view.context 
  12.                .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 
  13.        imm?.hideSoftInputFromWindow(view.windowToken, 0) 
  14.    } 
  15.    fun toggleSoftInput(viewView) { 
  16.        val imm = view.context 
  17.                .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 
  18.        imm?.toggleSoftInput(0, 0) 
  19.    } 

 

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2017-12-05 13:12:35

Android軟鍵盤參數(shù)

2024-06-20 12:30:34

2021-02-01 11:22:23

Windows 10Windows微軟

2024-05-06 08:28:09

Android窗口鍵盤

2021-08-07 15:31:45

Windows 10Windows微軟

2009-08-21 13:25:49

C#打開軟鍵盤

2017-07-03 17:20:55

Android軟鍵盤控制開發(fā)問題

2024-03-06 09:16:57

PAD設(shè)備kikaInput鴻蒙

2021-12-29 21:31:23

Windows 11Windows微軟

2023-06-27 06:58:38

機(jī)械鍵盤軸體

2013-04-01 17:05:28

2013-06-27 17:26:01

AndroidEditText

2020-03-24 09:34:00

移動端H5軟鍵盤

2021-02-20 22:15:44

Android 代碼操作系統(tǒng)

2021-07-13 09:49:08

鴻蒙HarmonyOS應(yīng)用

2019-04-25 10:20:22

H5軟鍵盤前端

2024-06-26 11:55:44

2021-11-09 23:10:24

Windows 11Windows微軟

2021-04-21 07:53:12

Java限流器管理

2019-10-08 10:37:46

設(shè)計技術(shù)程序員
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號