前一陣項(xiàng)目開發(fā)遇到一個(gè)問題趟佃。需求是這樣的,就是在開播的頁面昧捷,默認(rèn)進(jìn)入展示了兩排的標(biāo)簽闲昭。標(biāo)簽采用流式布局的形式。展示在直播標(biāo)題輸入框的下面靡挥。然后序矩,當(dāng)用戶點(diǎn)擊輸入框輸入文字的時(shí)候,這時(shí)跋破,軟鍵盤彈出簸淀,要求原本在輸入框下面的標(biāo)簽布局消失,當(dāng)用戶輸入完毒返,返回鍵使軟鍵盤消失后租幕,標(biāo)簽布局要重新展示出來。剛開始聽到這個(gè)需求的時(shí)候拧簸,沒覺著有任何的技術(shù)難度劲绪。無非監(jiān)聽一下軟鍵盤的顯示與消失么。當(dāng)監(jiān)聽到軟鍵盤顯示時(shí),將標(biāo)簽布局置為gone贾富;當(dāng)監(jiān)聽到軟鍵盤消失的時(shí)候歉眷,再將標(biāo)簽布局置為visible就OK的了。沒錯(cuò)颤枪,思路完全正確汗捡。但是,怎么監(jiān)聽確確實(shí)實(shí)折騰了我一個(gè)下午汇鞭。
在這里凉唐,要和廣大朋友聲明的一件比較操蛋的事就是,谷歌并沒有提供這一類接口來進(jìn)行軟鍵盤顯示與消失的監(jiān)聽霍骄。那么台囱,是不是我們就沒辦法獲取這一狀態(tài)的改變呢?當(dāng)然不是读整,我們可以監(jiān)聽根布局的布局高度變化來間接的對軟鍵盤的顯示與消失做出判斷簿训,并且還可以獲取到軟鍵盤的高度(注:當(dāng)清單文件中windowSoftInputMode="adjustNothing"此方法不生效)。這里有一個(gè)知識(shí)點(diǎn)還望大家自行科普一下米间,本篇文章就不做描述了强品,那就是Android中和軟鍵盤相關(guān)的Windowsoftinputmode屬性。這里留下一個(gè)鏈接屈糊,希望可以幫助到大家的榛。
Windowsoftinputmode屬性使用
接下來,直接上代碼逻锐,代碼中我做好了注釋夫晌,相信應(yīng)該很容易理解:
public class KeyboardChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {
private static final String TAG = "ListenerHandler";
private View mContentView; // 當(dāng)前界面的根視圖
private int mOriginHeight; // 此時(shí)根視圖的高度
private int mPreHeight; // 改變之前根視圖的高度
private KeyBoardListener mKeyBoardListen;
public KeyboardChangeListener(Activity activity) {
if (activity == null) {
Log.i(TAG, "contextObj is null");
return;
}
mContentView = findContentView(activity);
if (mContentView != null) {
addContentTreeObserver();
}
}
private View findContentView(Activity activity) {
return activity.findViewById(android.R.id.content);
}
private void addContentTreeObserver() {
mContentView.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@Override
public void onGlobalLayout() {
// 先獲取到當(dāng)前根視圖的高度
int currHeight = mContentView.getHeight();
if (currHeight == 0) {
return;
}
boolean hasChange = false;
if (mPreHeight == 0) {
mPreHeight = currHeight;
mOriginHeight = currHeight;
} else {
if (mPreHeight != currHeight) {
hasChange = true;
mPreHeight = currHeight;
} else {
hasChange = false;
}
}
if (hasChange) {
boolean isShow;
int keyboardHeight = 0;
// 當(dāng)當(dāng)前的根視圖高度和初始化時(shí)的高度一樣時(shí),說明此時(shí)軟鍵盤沒有顯示昧诱,是消失狀態(tài)
if (mOriginHeight == currHeight) {
//hidden
isShow = false;
} else {
// 此時(shí)晓淀,根視圖的高度減少了,而減少的部分就是軟鍵盤的高度盏档,軟鍵盤顯示狀態(tài)
//show
keyboardHeight = mOriginHeight - currHeight;
isShow = true;
}
if (mKeyBoardListen != null) {
mKeyBoardListen.onKeyboardChange(isShow, keyboardHeight);
}
}
}
public void setKeyBoardListener(KeyBoardListener keyBoardListen) {
this.mKeyBoardListen = keyBoardListen;
}
// 資源釋放
public void destroy() {
if (mContentView != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mContentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
public interface KeyBoardListener {
void onKeyboardChange(boolean isShow, int keyboardHeight);
}
}
以上便是實(shí)現(xiàn)軟件盤顯示和消失的監(jiān)聽凶掰,然后我們看一下具體的調(diào)用(布局中我設(shè)置了一個(gè)EditText,用于調(diào)起軟鍵盤):
public class MainActivity extends AppCompatActivity implements KeyboardChangeListener.KeyBoardListener {
private static final String TAG = "MainActivity";
private KeyboardChangeListener mKeyboardChangeListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mKeyboardChangeListener = new KeyboardChangeListener(this);
mKeyboardChangeListener.setKeyBoardListener(this);
}
@Override
public void onKeyboardChange(boolean isShow, int keyboardHeight) {
Log.d(TAG, "onKeyboardChange() called with: " + "isShow = [" + isShow + "], keyboardHeight = [" + keyboardHeight + "]");
}
}
下面是我在logcat中的log截圖蜈亩,實(shí)現(xiàn)了對軟鍵盤顯示和消失的監(jiān)聽懦窘,并且獲取到當(dāng)前軟鍵盤的高度: