自定義密碼輸入框
前言:看了好多自定義控制元件說實話道理上也可以說出一下但是實際上讓我實實在在的想要做出一個成功和考慮齊全的view來說還是有些困難,文章也許有所借鑑,但確實是自己真真實實弄出來的,主要是記錄一些實際的經驗和點點滴滴,專案暫時不算緊急,提升自己隨時隨刻
首先,貼出我們想要的實際效果圖
通過以上的效果圖,現在咱們做下實際的分析,然後細緻到相應的程式碼實現。要實現的功能如下:
1.密碼框分為下劃線和方格
2.密碼分為明文和密文*
3.有閃動的游標,可以隨著密碼的位置向後平移
4.調動輸入法,將使用者輸入的內容放到對應位置
實現思路,1.畫邊框(根據密碼的長度畫對應樣式的邊框)
2.畫密碼或者密文(根據屬性指示和密碼長度,動態畫對應的密碼或者密文)
3.畫游標(根據現在密碼長度獲取游標位置,為讓其閃動,我們可以使用timer讓他切換是否顯示)
4.根據觸控時間,呼叫輸入法,使用onkeylistener將使用者輸入的內容放到對應的陣列內。
2.3步驟都需要根據密碼的長度去判斷現在要畫多少個字元
一,暴露屬性和介面
我有一個夢想就是讓其他人都用我的控制元件,那麼咱們需要思考的是對於他們來說最需要的是什麼,就需要向他們暴露對應的一些屬性或者介面就好
對於咱們的控制元件來說,
外面邊框的表達形式,包括密碼的長度,邊框顏色,邊框線條粗細,密碼之間的間隔,密文的樣式,閃動游標的顏色,大小等等
所以咱們通過自定義屬性來完成這些屬性的暴露,忘了嗎?通過attrs.xml來定義這些實際的屬性
二,引入自定義屬性
首先需要做的事情是,新建個view這裡我們是PasswordView 然後繼承與view,然後建造對應的構造方法,不同欄位的構造方法相信大家已經知道對應不同的作用了。然後需要引入對應的屬性,就是使用TypeArrary
三,為自己量身打造 onMeasure
case MeasureSpec.UNSPECIFIED:
case MeasureSpec.AT_MOST:
//沒有指定大小,寬度 = 單個密碼框大小 * 密碼位數 + 密碼框間距 *(密碼位數 - 1)
case MeasureSpec.EXACTLY:
//指定大小,寬度 = 指定的大小
//密碼框大小等於 (寬度 - 密碼框間距 *(密碼位數 - 1)) / 密碼位數
四。開始畫邊框文字和游標
無論是話邊框還是畫下劃線,這個比較簡單,只需要把座標點控制好即可,主要演算法如下
// 起始點x為paddingLeft + (單個密碼框大小 + 密碼框邊距) * i , 起始點y為paddingTop + 單個密碼框大小
畫游標跟上面不同點就是多向右平移了半個字元的寬度
畫文字,這裡需要注意一點,文字的起始點的xy座標的另類性,為保證文字在框居中顯示,故需要首先測量下文字,然後根據文字的寬高去設定起始的xy座標,
五,讓密碼長度動起來
setFocusableInTouchMode(true);//吊起輸入法必備,否則釣不起來
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER; //輸入型別為數字
return super.onCreateInputConnection(outAttrs);
}
這個方法會讓輸入法被吊起之後直接顯示數字鍵盤
setOnKeyListener(new MyKeyListener());通過自定義的keylitener將監聽使用者的輸入的密碼,然後將密碼放到對應的陣列內
對於游標的閃動咱們定義了一個timer
下面這個方法讓timer隨著載入而載入,停止而停止
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
timer.cancel();
}
下面這個方法讓框發生變化時輸入法發生相應的隱藏
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (!hasWindowFocus) {
inputMethod.hideSoftInputFromWindow(this.getWindowToken(), 0);
}
}
就到此吧,第一次發部落格多多見諒