欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:Flutter 驗證碼輸入框

柚子快報邀請碼778899分享:Flutter 驗證碼輸入框

http://yzkb.51969.com/

前言:

驗證碼輸入框很常見:處理不好 bug也會比較多 想實現(xiàn)方法很多,這里列舉一種完美方式,完美兼容 軟鍵盤粘貼方式

效果如下:

之前使用 uniapp 的方式實現(xiàn)過一次 兩種方式(原理相同):

input 驗證碼 密碼 輸入框_input密碼輸入框-CSDN博客文章瀏覽閱讀3.9k次,點贊3次,收藏6次。前言:uniapp 在做需求的時候,經(jīng)常會遇到;驗證碼輸入框 或者 密碼輸框 自定義樣式輸入框 或者 格式化顯示 銀行卡 手機號碼等等:這里總結(jié)了兩種 常用的實現(xiàn)方式;從這兩種實現(xiàn)方式 其實也能延伸出其他的顯示 方式;先看樣式: 自己實現(xiàn) 光標(biāo)閃爍動畫第一種:可以識別 獲得焦點 失去焦點第一種實現(xiàn)的思路: 實際上就是,下層的真實 input 負(fù)責(zé)響應(yīng)系統(tǒng)的輸入,上面一層負(fù)責(zé)顯示 應(yīng)為輸入框在手機端會 出現(xiàn)長按 學(xué)著 復(fù)制等等 輸入框自帶屬..._input密碼輸入框https://blog.csdn.net/nicepainkiller/article/details/124384995?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171723341916800226511048%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=171723341916800226511048&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-124384995-null-null.nonecase&utm_term=input&spm=1018.2226.3001.4450

實現(xiàn)原理拆解:

輸入框區(qū)域我們分割成兩層:

6個黃色的區(qū)域 僅僅做展示,中間的黑色是一個動畫 模擬光標(biāo)閃爍 或者 展示 輸入的數(shù)字最上層蓋一個 輸入框控件 接收輸入事件,設(shè)置透明度 0.00001,設(shè)置不支持長按 選取復(fù)制,僅僅支持?jǐn)?shù)字

這樣一來就很明了, 邏輯也很簡單

?具體實現(xiàn):

要實現(xiàn) 軟鍵盤的 填充事件,所以我們需要動態(tài)監(jiān)聽 輸入事件

@override

void initState() {

// TODO: implement initState

super.initState();

// 自動彈出軟鍵盤

Future.delayed(Duration.zero, () {

FocusScope.of(context).requestFocus(_focusNode);

});

// 監(jiān)聽粘貼事件

_textEditingController.addListener(() {

if (Clipboard.getData('text/plain') != null) {

Clipboard.getData('text/plain').then((value) {

if (value != null && value.text != null) {

if (value.text!.isNotEmpty && value.text!.length == 6) {

if (RegExp(AppRegular.numberAll).firstMatch(value.text!) !=

null) {

_textEditingController.text = value!.text!;

//取完值 置為 null

Clipboard.setData(const ClipboardData(text: ''));

//設(shè)置輸入框光標(biāo)到末尾 防止某些情況下 光標(biāo)跑到前面,鍵盤無法刪除輸入字符

_textEditingController.selection = TextSelection.fromPosition(

TextPosition(offset: _textEditingController.text.length),

);

}

}

}

});

}

setState(() {

_arrayCode = List.filled(widget.length, '');

for (int i = 0; i < _textEditingController.value.text.length; i++) {

_arrayCode[i] = _textEditingController.value.text.substring(i, i + 1);

}

});

if (_textEditingController.value.text.length == 6) {

//防止重復(fù)觸發(fā) 回調(diào)事件

if (!_triggerState) {

_triggerState = true;

AppScreen.showToast('輸入完成:${_textEditingController.value.text}');

widget.onComplete(_textEditingController.value.text);

}

} else {

_triggerState = false;

}

});

} 輸入框的設(shè)置,禁止長按 child: TextField(

enableInteractiveSelection: false, // 禁用長按復(fù)制功

maxLength: widget.length,

focusNode: _focusNode,

maxLines: 1,

controller: _textEditingController,

style: AppTextStyle.textStyle_32_333333,

inputFormatters: [InputFormatter(AppRegular.numberAll)],

decoration: const InputDecoration(

focusedBorder: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

disabledBorder: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

enabledBorder: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

border: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

counterText: '', //取消文字計數(shù)器

),

) 頁面動畫的展示,F(xiàn)adeTransition 為了性能優(yōu)化到我們動畫縮小到最小范圍 class InputFocusWidget extends StatefulWidget {

const InputFocusWidget({Key? key}) : super(key: key);

@override

State createState() => _InputFocusWidgetState();

}

class _InputFocusWidgetState extends State

with TickerProviderStateMixin {

late AnimationController controller;

late Animation animation;

@override

void initState() {

// TODO: implement initState

super.initState();

controller = AnimationController(

duration: const Duration(milliseconds: 600), vsync: this);

animation = CurvedAnimation(parent: controller, curve: Curves.easeIn);

controller.repeat(min: 0, max: 1, reverse: true);

}

@override

void dispose() {

controller.dispose();

// TODO: implement dispose

super.dispose();

}

@override

Widget build(BuildContext context) {

return FadeTransition(

opacity: animation,

child: Container(

color: Colors.green,

width: double.infinity,

height: double.infinity,

),

);

}

}

完整代碼:

?因為里面使用到我自己封裝的一些工具,用的時候需要你轉(zhuǎn)成自己的

import 'package:flutter/material.dart';

import 'package:flutter/services.dart';

import 'package:game/utils/app_screen.dart';

import 'package:game/wrap/extension/extension.dart';

import 'package:game/wrap/overlay/app_overlay.dart';

import '../const/app_regular.dart';

import '../const/app_textStyle.dart';

import 'input_formatter.dart';

class InputWithCode extends StatefulWidget {

final int length;

final ValueChanged onComplete;

const InputWithCode(

{required this.length, required this.onComplete, Key? key})

: super(key: key);

@override

State createState() => _InputWithCodeState();

}

class _InputWithCodeState extends State {

final TextEditingController _textEditingController = TextEditingController();

bool _triggerState = false;

late List _arrayCode = List.filled(widget.length, '');

final FocusNode _focusNode = FocusNode();

@override

void initState() {

// TODO: implement initState

super.initState();

// 自動彈出軟鍵盤

Future.delayed(Duration.zero, () {

FocusScope.of(context).requestFocus(_focusNode);

});

// 監(jiān)聽粘貼事件

_textEditingController.addListener(() {

if (Clipboard.getData('text/plain') != null) {

Clipboard.getData('text/plain').then((value) {

if (value != null && value.text != null) {

if (value.text!.isNotEmpty && value.text!.length == 6) {

if (RegExp(AppRegular.numberAll).firstMatch(value.text!) !=

null) {

_textEditingController.text = value!.text!;

Clipboard.setData(const ClipboardData(text: ''));

_textEditingController.selection = TextSelection.fromPosition(

TextPosition(offset: _textEditingController.text.length),

);

}

}

}

});

}

setState(() {

_arrayCode = List.filled(widget.length, '');

for (int i = 0; i < _textEditingController.value.text.length; i++) {

_arrayCode[i] = _textEditingController.value.text.substring(i, i + 1);

}

});

if (_textEditingController.value.text.length == 6) {

if (!_triggerState) {

_triggerState = true;

AppScreen.showToast('輸入完成:${_textEditingController.value.text}');

widget.onComplete(_textEditingController.value.text);

}

} else {

_triggerState = false;

}

});

}

@override

Widget build(BuildContext context) {

return Container(

width: double.infinity,

height: double.infinity,

child: Stack(

children: [

Center(

child: Row(

children: _arrayCode

.asMap()

.map(

(index, value) => MapEntry(

index,

Container(

width: 80.cale,

height: 80.cale,

margin: EdgeInsets.symmetric(horizontal: 10.cale),

decoration: BoxDecoration(

border: Border(

bottom: BorderSide(

width: 3.cale,

color: value != ''

? Colors.amberAccent

: Colors.amberAccent.withOpacity(0.5),

),

),

),

child: index != _textEditingController.value.text.length

? Center(

child: Text(

value,

style: AppTextStyle.textStyle_40_1A1A1A_Bold,

),

)

: Center(

child: SizedBox(

width: 3.cale,

height: 40.cale,

child: const InputFocusWidget(),

),

),

),

),

)

.values

.toList(),

),

),

Opacity(

opacity: 0.0001,

child: SizedBox(

height: double.infinity,

width: double.infinity,

child: TextField(

enableInteractiveSelection: false, // 禁用長按復(fù)制功

maxLength: widget.length,

focusNode: _focusNode,

maxLines: 1,

controller: _textEditingController,

style: AppTextStyle.textStyle_32_333333,

inputFormatters: [InputFormatter(AppRegular.numberAll)],

decoration: const InputDecoration(

focusedBorder: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

disabledBorder: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

enabledBorder: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

border: OutlineInputBorder(

borderSide:

BorderSide(width: 0, color: Colors.transparent)),

counterText: '', //取消文字計數(shù)器

),

),

),

),

],

),

);

}

}

class InputFocusWidget extends StatefulWidget {

const InputFocusWidget({Key? key}) : super(key: key);

@override

State createState() => _InputFocusWidgetState();

}

class _InputFocusWidgetState extends State

with TickerProviderStateMixin {

late AnimationController controller;

late Animation animation;

@override

void initState() {

// TODO: implement initState

super.initState();

controller = AnimationController(

duration: const Duration(milliseconds: 600), vsync: this);

animation = CurvedAnimation(parent: controller, curve: Curves.easeIn);

controller.repeat(min: 0, max: 1, reverse: true);

}

@override

void dispose() {

controller.dispose();

// TODO: implement dispose

super.dispose();

}

@override

Widget build(BuildContext context) {

return FadeTransition(

opacity: animation,

child: Container(

color: Colors.green,

width: double.infinity,

height: double.infinity,

),

);

}

}

使用:

?控件名稱:InputWithCode?length:驗證碼長度onComplete: 輸入完成回調(diào)

Container(

child: InputWithCode(

length: 6,

onComplete: (code) => {

print('InputWithCode:$code'),

},

),

width: double.infinity,

height: 200.cale,

),

柚子快報邀請碼778899分享:Flutter 驗證碼輸入框

http://yzkb.51969.com/

好文閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/18977736.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄