Flutter 完美的驗證碼輸入框

老孟導讀:剛開始看到這個功能的時候一定覺得so easy,開始的時候我也是這麼覺得的,這還不簡單,然而真正寫的時候才發現並沒有想象的那麼簡單。

先上圖,不上圖你們都不想看,我難啊,到Github:https://github.com/781238222/flutter-do 上給個小星星可還行,如果能fork一下,那更是感激不盡。

言歸正傳,完成驗證碼輸入框經歷了4個階段,雖然前3個嘗試是失敗的,但也想和大家分享下,避免大家再走彎路。

第一階段:開始的時候,我認爲直接修改TextField控件,改改外觀就可以了,所以我就直接去改TextField的屬性,研究了一遍,發現無法達到要求,系統提供的屬性無法達到我的要求。

第二階段:既然原生的TextField無法實現我的效果,那就重寫一個(並不是全部重寫,而是把源代碼copy出來,修改控制外觀的代碼),於是我就去copy源代碼了,可真正copy的時候發現TextField的關係比較複雜,並不是一個簡單的StatefulWidget控件,而且需要計算字符的寬度,此方案雖然能實現,但想想就複雜,果斷拋棄。

第三階段:用6個TextField,每一個控制一個驗證碼,雖然樣式及佈局上很容易達到要求,但焦點控制問題非常致命,此方案也pass。

第四階段:經過上面失敗的經歷,最後我才用如下方案:一個TextField用於輸入,而驗證碼的顯示使用Container,驗證碼覆蓋在TextField之上,用戶無法感知到TextField,這是目前爲止我發現的最完美的方案。

焦點問題

正常情況下,出現驗證碼的頁面會彈出鍵盤,此效果很好實現,指需給TextField指定自動獲取焦點即可,代碼如下:

TextField(
	autofocus:true,
	...
)

如果頁面還有其他輸入框,那麼就不一定要獲取焦點了,因此是否獲取焦點需要交給用戶來決定。

如果開始沒有獲取焦點就出現了一個問題,用戶點擊“驗證碼”的時候需要獲取焦點,獲取焦點方法如下:

GestureDetector(
  onTap: () {
    FocusScope.of(context).requestFocus(_focusNode);
  },
  ...
)

給整個控件的外層添加點擊事件,_focusNode爲TextField的focusNode

輸入完成後,通常需要關閉鍵盤,即TextField失去焦點,失去焦點方法如下:

_focusNode.unfocus();

使用

使用非常簡單,如下:

Container(
  height: 45,
  child: VerificationBox(),
)

效果如下:

設置驗證碼的數量,比如設置4個:

VerificationBox(
  count: 4,
)

效果如下:

設置樣式,包括邊框的顏色、寬度、圓角:

VerificationBox(
  borderColor: Colors.lightBlue,
  borderWidth: 3,
  borderRadius: 50,
)

效果如下:

除了“盒子”樣式,還支持下劃線樣式:

VerificationBox(
  type: VerificationBoxItemType.underline,
)

效果如下:

設置數字的樣式:

VerificationBox(
  textStyle: TextStyle(color: Colors.lightBlue),
)

效果如下:

顯示光標,設置光標樣式:

VerificationBox(
  showCursor: true,
  cursorWidth: 2,
  cursorColor: Colors.red,
  cursorIndent: 10,
  cursorEndIndent: 10,
)

效果如下:

還可以設置光標爲整個邊框,如下:

VerificationBox(
  focusBorderColor: Colors.lightBlue,
)

效果如下:

終極大招,如果你覺得這個效果不好,你可以自定義decoration

VerificationBox(
    decoration: BoxDecoration(
      image: DecorationImage(image: AssetImage('images/box.png')),
    ),
    textStyle: TextStyle(color: Colors.lightBlue),
  ),
)

效果如下:

驗證碼輸入完成後回調onSubmitted,用法如下:

VerificationBox(
  onSubmitted: (value){
    print('$value');
  },
)

輸入完成後,默認鍵盤消失,設置爲不消失,代碼如下:

VerificationBox(
  unfocus: false,
)

交流

如果你對Flutter還有疑問或者技術方面的疑惑,歡迎加入Flutter交流羣(微信:laomengit)。

同時也歡迎關注我的Flutter公衆號【老孟程序員】,公衆號首發Flutter的相關內容。

Flutter地址:http://laomengit.com 裏面包含160多個組件的詳細用法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章