CaptainAndroid.png
相信看到這個(gè)標(biāo)題,大家都會(huì)潛意識(shí)覺得:Activity中沒有可以復(fù)寫的方法么?或者說,沒有什么listener可以讓我們使用么?
抱歉,真的沒有,我們潛意識(shí)都是以為系統(tǒng)會(huì)提供,其實(shí)系統(tǒng)提供的是InputMethodManager,讓我們控制鍵盤的彈出和隱藏,而不是鍵盤彈出和隱藏觸發(fā)事件。
我們?cè)陂_發(fā)中經(jīng)常會(huì)遇到軟鍵盤遮擋住了輸入框,而直接把輸入框往上頂adjustResize這種方法過于暴力影響美觀,我們希望鍵盤彈出時(shí)動(dòng)態(tài)的去改變布局。這時(shí)候,便用到了監(jiān)聽鍵盤彈起事件的功能。
正題
好了,進(jìn)入正題,如何監(jiān)聽鍵盤的彈出和隱藏呢?
- 目前通用的方法是,由于鍵盤彈起與隱藏,會(huì)使得layout的布局發(fā)生變化,通過布局的大小變化觸發(fā)的事件實(shí)現(xiàn)鍵盤事件的觸發(fā)(該方法的缺點(diǎn)是,當(dāng)設(shè)置為全屏模式時(shí),由于布局強(qiáng)制充滿全屏,此時(shí)布局大小不會(huì)再改變,該方法也就失效了。至少我這邊是這樣的 ->_-> )
我們可以復(fù)寫一個(gè)ViewGroup的onSizeChanged方法,然后我們的根布局就是這個(gè)AdjustSizeLinearLayout,此時(shí)當(dāng)鍵盤彈起會(huì)觸發(fā)我們的監(jiān)聽器。
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;
public class AdjustSizeLinearLayout extends LinearLayout{
public AdjustSizeLinearLayout(Context context) {
super(context);
}
public AdjustSizeLinearLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public AdjustSizeLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
private int mChangeSize = 200;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.e("###xiamin", "change" + w + " " + h + " " + oldw + " " + oldh);
if (oldw == 0 || oldh == 0)
return;
if (boardListener != null) {
if (oldw != 0 && h - oldh < -mChangeSize) {
Log.e("###xiamin","鍵盤彈出"+ "change" + w + " " + h + " " + oldw + " " + oldh);
ToastUtils.showToast(getContext(), "鍵盤彈出");
boardListener.keyBoardVisable(Math.abs(h - oldh));
}
if (oldw != 0 && h - oldh > mChangeSize) {
ToastUtils.showToast(getContext(), "鍵盤下去");
Log.e("###xiamin","鍵盤結(jié)束"+ "change" + w + " " + h + " " + oldw + " " + oldh);
boardListener.keyBoardInvisable(Math.abs(h - oldh));
}
}
}
public interface SoftkeyBoardListener {
public void keyBoardVisable(int move);
public void keyBoardInvisable(int move);
}
SoftkeyBoardListener boardListener;
public void setSoftKeyBoardListener(SoftkeyBoardListener boardListener) {
this.boardListener = boardListener;
}
}
- 該方法來自于github,
使用簡單
make activity:
android:windowSoftInputMode="adjustResize"
java:
new KeyboardChangeListener(this).setKeyBoardListener(new KeyboardChangeListener.KeyBoardListener() {
@Override
public void onKeyboardChange(boolean isShow, int keyboardHeight) {
Log.d(TAG, "isShow = [" + isShow + "], keyboardHeight = [" + keyboardHeight + "]");
}
});
雖然不是根據(jù)布局大小變化來判斷的,但是根據(jù)ViewTreeObserver.OnGlobalLayoutListener,
@Override
public void onGlobalLayout() {
int currHeight = mContentView.getHeight();
if (currHeight == 0) {
Log.i(TAG, "currHeight is 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);
}
}
}
還是根據(jù)高度變化來間接判斷鍵盤是否彈出的。
總結(jié)
Android系統(tǒng)并沒有給我們提供監(jiān)聽鍵盤彈出的方法,我們只能自己監(jiān)聽view的高度變化來間接判斷鍵盤是不是彈出了。同時(shí)希望大家有更好的方法提供
謝謝大家閱讀,如有幫助,來個(gè)喜歡或者關(guān)注吧!
本文作者:Anderson/Jerey_Jobs
簡書地址:Anderson大碼渣
github地址:Jerey_Jobs