hah.png
前一陣項目開發遇到一個問題。需求是這樣的,就是在開播的頁面,默認進入展示了兩排的標簽。標簽采用流式布局的形式。展示在直播標題輸入框的下面。然后,當用戶點擊輸入框輸入文字的時候,這時,軟鍵盤彈出,要求原本在輸入框下面的標簽布局消失,當用戶輸入完,返回鍵使軟鍵盤消失后,標簽布局要重新展示出來。剛開始聽到這個需求的時候,沒覺著有任何的技術難度。無非監聽一下軟鍵盤的顯示與消失么。當監聽到軟鍵盤顯示時,將標簽布局置為gone;當監聽到軟鍵盤消失的時候,再將標簽布局置為visible就OK的了。沒錯,思路完全正確。但是,怎么監聽確確實實折騰了我一個下午。
在這里,要和廣大朋友聲明的一件比較操蛋的事就是,谷歌并沒有提供這一類接口來進行軟鍵盤顯示與消失的監聽。那么,是不是我們就沒辦法獲取這一狀態的改變呢?當然不是,我們可以監聽根布局的布局高度變化來間接的對軟鍵盤的顯示與消失做出判斷,并且還可以獲取到軟鍵盤的高度(注:當清單文件中windowSoftInputMode="adjustNothing"此方法不生效)。這里有一個知識點還望大家自行科普一下,本篇文章就不做描述了,那就是Android中和軟鍵盤相關的Windowsoftinputmode屬性。這里留下一個鏈接,希望可以幫助到大家。
Windowsoftinputmode屬性使用
接下來,直接上代碼,代碼中我做好了注釋,相信應該很容易理解:
public class KeyboardChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {
private static final String TAG = "ListenerHandler";
private View mContentView; // 當前界面的根視圖
private int mOriginHeight; // 此時根視圖的高度
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() {
// 先獲取到當前根視圖的高度
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;
// 當當前的根視圖高度和初始化時的高度一樣時,說明此時軟鍵盤沒有顯示,是消失狀態
if (mOriginHeight == currHeight) {
//hidden
isShow = false;
} else {
// 此時,根視圖的高度減少了,而減少的部分就是軟鍵盤的高度,軟鍵盤顯示狀態
//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);
}
}
以上便是實現軟件盤顯示和消失的監聽,然后我們看一下具體的調用(布局中我設置了一個EditText,用于調起軟鍵盤):
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截圖,實現了對軟鍵盤顯示和消失的監聽,并且獲取到當前軟鍵盤的高度:
log.png