問題來源
這段時間在忙公司的新項目。在注冊頁面需要一個驗證碼填寫的view。大概長這樣。
想了想,先去github上找找資源吧!感覺 GridPasswordView 這個不錯。
我:boss啊,能不能先模仿支付寶密碼那樣的形式啊
boss:恩,好吧。
我:謝謝boss,boss真帥
因為注冊頁面布局比較復(fù)雜。大概是RelativeLayout和LinearLayout嵌套了幾層。當(dāng)我進(jìn)入了驗證碼輸入的這個過程的時候,秉持著一個程序員的嚴(yán)謹(jǐn),我需要測試各種情況,模仿用戶會遇到的各種情況。我把鍵盤隱藏了下去,然后再次點擊。咦!鍵盤上來了,填寫驗證碼的view呢?去哪了?陷入了深深的悲傷之中。看來這個view,還是要自己去研究怎么擼了。
生活總會在你覺得你能成功偷懶的時候,給你當(dāng)頭棒喝 ---牛頓
先看看鍵盤問題吧。如果鍵盤能把整屏幕頂上去,那也能解決問題啊!
瀏覽了一番,發(fā)現(xiàn)了如下要點:
android:windowSoftInputMode="adjustPan"
android:windowSoftInputMode="adjustResize"
分別在代碼里面嘗試了一下,adjustPan是平移屏幕,就是默認(rèn)的EditText默認(rèn)的鍵盤平移效果,不能頂起GridPasswordView
adjustResize的效果是屏幕控件重新計算尺寸,壓縮尺寸,使得鍵盤可以全部顯示在屏幕中。在我的項目中,只能頂起一部分控件,背景卻沒有變化,導(dǎo)致布局錯亂。
既然鍵盤不行,我去自己寫個view可以不咯
其實,現(xiàn)在要解決我的問題,就是需要一個view。該view能像EditText一樣,能正常被鍵盤頂起,就行了。
在這里,真的很感謝一篇文章。這篇文章的主要思想,就是用一個view,直接獲取用戶輸入。簡單粗暴,i like it!我先把這個作者的view,放進(jìn)了自己的布局文件里,試了一下,yes!沒有問題,能被正常頂起!
開始研究代碼~
在這里,我只放出我覺得是核心的代碼
private InputMethodManager input;// 輸入法管理
@Override
public boolean onCheckIsTextEditor() {return true;}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;//輸入類型為數(shù)字
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
return new MyInputConnection(this, false);
}
class MyInputConnection extends BaseInputConnection {
public MyInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
//這里是接受輸入法的文本的,我們只處理數(shù)字,所以什么操作都不做
return super.commitText(text, newCursorPosition);
}
@Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
//軟鍵盤的刪除鍵 DEL 無法直接監(jiān)聽,自己發(fā)送del事件
if (beforeLength == 1 && afterLength == 0) {
return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
&& super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
}
return super.deleteSurroundingText(beforeLength, afterLength);
}
}
還有就是onTouch的鍵盤彈起和onWindowsFocusChanged失去焦點收起鍵盤的處理。
View類下的方法
boolean onCheckIsTextEditor ()
官方的解釋:
Check whether the called view is a text editor, in which case it would make sense to automatically display a soft input window for it. Subclasses should override this if they implement onCreateInputConnection(EditorInfo) to return true if a call on that method would return a non-null InputConnection, and they are really a first-class editor that the user would normally start typing on when the go into a window containing your view.
The default implementation always returns false. This does not mean that its onCreateInputConnection(EditorInfo) will not be called or the user can not otherwise perform edits on your view; it is just a hint to the system that this is not the primary purpose of this view.
大概的意思就是這個決定這個View是不是一個文本編輯器。如果返回true,則認(rèn)為這個view是可以被編輯的,那么用戶也必須自己實現(xiàn)onCreateInputConnection(EditorInfo) 來決定鍵盤的樣式,或者是不是應(yīng)該彈出鍵盤。(大概的意思就是這個吧,理解有錯誤請大家及時指出,在這里跪謝了~)。
下一步呢?
鍵盤頂起view是沒問題啦。驗證碼那個樣子,該怎么解決呢?
說到自定義view,那就不得不說到ViewGroup啦,實現(xiàn)onLayout這個方法,就可以自定義自己的view啦!ViewGroup可以addView想添加多少添加多少嘛。但是,RelativeLayout是ViewGroup的子類啊!在xml布局文件里面寫好所有布局,在RelativeLayout中使用getChild的方法,獲取控件對象以后,布局可以隨意控制了嘛~用了四個SquareItemLayout,每個SquareItemLayout里面一個ImageView(驗證碼邊框),TextView(數(shù)字顯示),ImageView(光標(biāo)顯示)。
大概就是這樣了。通過這件事,對Android的鍵盤控制更加了解了。對自定義Viewyou 了更近一步的了解。
接下來的目標(biāo)
RxJava RxAndroid Dagger2