網站首頁 編程語言 正文
Flutter實現滑動塊驗證碼功能,供大家參考,具體內容如下
本文實現的是一個用于登錄時,向右滑動滑動塊到最右邊完成驗證的一個功能。當滑動未到最右邊時,滑動塊回彈回左邊起始位置。
import 'package:flutter/material.dart'; ? class SlideVerifyWidget extends StatefulWidget{ ? ? /// 背景色 ? final Color backgroundColor; ? /// 滑動過的顏色 ? final Color slideColor; ? /// 邊框顏色 ? final Color borderColor; ? ? final double height; ? final double width; ? ? final VoidCallback verifySuccessListener; ? ? const SlideVerifyWidget({ ? ? Key key, ? ? this.backgroundColor = Colors.blueGrey, ? ? this.slideColor = Colors.green, ? ? this.borderColor = Colors.grey, ? ? this.height = 44, ? ? this.width = 240, ? ? this.verifySuccessListener ? }) : super(key: key); ? ? @override ? StatecreateState() { ? ? return SlideVerifyState(); ? } ? } ? class SlideVerifyState extends State with TickerProviderStateMixin{ ? ? double height; ? double width ; ? ? double sliderDistance = 0; ? ? double initial = 0.0; ? ? /// 滑動塊寬度 ? double sliderWidth = 64; ? ? /// 驗證是否通過,滑動到最右方為通過 ? bool verifySuccess = false; ? ? /// 是否允許拖動 ? bool enableSlide = true; ? ? AnimationController _animationController; ? Animation _curve; ? ? @override ? void initState() { ? ? super.initState(); ? ? this.width = widget.width; ? ? this.height = widget.height; ? ? _initAnimation(); ? } ? ? @override ? void dispose() { ? ? _animationController?.dispose(); ? ? super.dispose(); ? } ? ? ? @override ? Widget build(BuildContext context) { ? ? return GestureDetector( ? ? ? onHorizontalDragStart: (DragStartDetails details){ ? ? ? ? if(!enableSlide){ ? ? ? ? ? return; ? ? ? ? } ? ? ? ? initial = details.globalPosition.dx; ? ? ? }, ? ? ? onHorizontalDragUpdate: (DragUpdateDetails details){ ? ? ? ? if(!enableSlide){ ? ? ? ? ? return; ? ? ? ? } ? ? ? ? sliderDistance = details.globalPosition.dx - initial; ? ? ? ? if(sliderDistance < 0){ ? ? ? ? ? sliderDistance = 0; ? ? ? ? } ? ? ? ? /// 當滑動到最右邊時,通知驗證成功,并禁止滑動 ? ? ? ? if(sliderDistance > width - sliderWidth){ ? ? ? ? ? sliderDistance = width - sliderWidth; ? ? ? ? ? enableSlide = false; ? ? ? ? ? verifySuccess = true; ? ? ? ? ? if(widget.verifySuccessListener != null){ ? ? ? ? ? ? widget.verifySuccessListener(); ? ? ? ? ? } ? ? ? ? } ? ? ? ? setState(() { ? ? ? ? }); ? ? ? }, ? ? ? onHorizontalDragEnd: (DragEndDetails details){ ? ? ? ? /// 滑動松開時,如果未達到最右邊,啟動回彈動畫 ? ? ? ? if(enableSlide){ ? ? ? ? ? enableSlide = false; ? ? ? ? ? _animationController.forward(); ? ? ? ? } ? ? ? }, ? ? ? child: Container( ? ? ? ? height: height, ? ? ? ? width: width, ? ? ? ? decoration: BoxDecoration( ? ? ? ? ? color: widget.backgroundColor, ? ? ? ? ? border: Border.all(color: widget.borderColor), ? ? ? ? ? ? /// 圓角實現 ? ? ? ? ? borderRadius: BorderRadius.all(new Radius.circular(height)) ? ? ? ? ), ? ? ? ? child: Stack( ? ? ? ? ? children: [ ? ? ? ? ? ? Positioned( ? ? ? ? ? ? ? top: 0, ? ? ? ? ? ? ? left: 0, ? ? ? ? ? ? ? child: Container( ? ? ? ? ? ? ? ? height: height - 2, ? ? ? ? ? ? ? ? /// 當slider滑動到距左邊只有兩三像素距離時,已滑動背景會有一點點渲染出邊框范圍, ? ? ? ? ? ? ? ? /// 因此當滑動距離小于1時,直接將寬度設置為0,解決滑動塊返回左邊時導致的綠色閃動,但如果是緩慢滑動到左邊該問題仍沒解決 ? ? ? ? ? ? ? ? width: sliderDistance < 1? 0 : sliderDistance + sliderWidth / 2, ? ? ? ? ? ? ? ? decoration: BoxDecoration( ? ? ? ? ? ? ? ? ? ? color: widget.slideColor, ? ? ? ? ? ? ? ? ? ? /// 圓角實現 ? ? ? ? ? ? ? ? ? ? borderRadius: BorderRadius.all(new Radius.circular(height / 2)) ? ? ? ? ? ? ? ? ), ? ? ? ? ? ? ? ), ? ? ? ? ? ? ), ? ? ? ? ? ? Center( ? ? ? ? ? ? ? child: Text(verifySuccess?"驗證成功":"請按住滑塊,拖動到最右邊", style: TextStyle(color: verifySuccess?Colors.white:Colors.black54, fontSize: 14),), ? ? ? ? ? ? ), ? ? ? ? ? ? Positioned( ? ? ? ? ? ? ? top: 0, ? ? ? ? ? ? ? /// 此處將sliderDistance距離往左偏2是解決當滑動塊滑動到最右邊時遮擋外部邊框 ? ? ? ? ? ? ? left: sliderDistance > sliderWidth ? sliderDistance - 2 : sliderDistance, ? ? ? ? ? ? ? child: Container( ? ? ? ? ? ? ? ? width: sliderWidth, ? ? ? ? ? ? ? ? height: height - 2 , ? ? ? ? ? ? ? ? alignment: Alignment.center, ? ? ? ? ? ? ? ? decoration: BoxDecoration( ? ? ? ? ? ? ? ? ? ? color: Colors.white, ? ? ? ? ? ? ? ? ? ? border: Border.all(color: widget.borderColor), ? ? ? ? ? ? ? ? ? ? /// 圓角實現 ? ? ? ? ? ? ? ? ? ? borderRadius: BorderRadius.all(new Radius.circular(height)) ? ? ? ? ? ? ? ? ), ? ? ? ? ? ? ? ? child: Row( ? ? ? ? ? ? ? ? ? mainAxisAlignment: MainAxisAlignment.center, ? ? ? ? ? ? ? ? ? children: [ ? ? ? ? ? ? ? ? ? ? SizedBox(width: 6,), ? ? ? ? ? ? ? ? ? ? Image.asset("assets/images/ic_safety.png", height: 24, width: 24,), ? ? ? ? ? ? ? ? ? ? Image.asset("assets/images/ic_next_primary.png", height: 16, width: 16,), ? ? ? ? ? ? ? ? ? ? /// 因為向右箭頭有透明邊距導致兩個箭頭間隔過大,因此將第二個箭頭向左偏移,如果切圖無邊距則不用偏移 ? ? ? ? ? ? ? ? ? ? Transform( ? ? ? ? ? ? ? ? ? ? ? transform: Matrix4.translationValues(-8, 0, 0), ? ? ? ? ? ? ? ? ? ? ? child: Image.asset("assets/images/ic_next_primary.png", height: 16, width: 16,), ? ? ? ? ? ? ? ? ? ? ), ? ? ? ? ? ? ? ? ? ], ? ? ? ? ? ? ? ? ), ? ? ? ? ? ? ? ), ? ? ? ? ? ? ) ? ? ? ? ? ], ? ? ? ? ), ? ? ? ), ? ? ); ? } ? ? /// 回彈動畫 ? void _initAnimation(){ ? ? _animationController = AnimationController( ? ? ? ? duration: const Duration(milliseconds: 300), vsync: this); ? ? _curve = CurvedAnimation(parent: _animationController, curve: Curves.easeOut); ? ? _curve.addListener(() { ? ? ? setState(() { ? ? ? ? sliderDistance = sliderDistance - sliderDistance * _curve.value; ? ? ? ? if(sliderDistance <= 0){ ? ? ? ? ? sliderDistance = 0; ? ? ? ? } ? ? ? }); ? ? }); ? ? _animationController.addStatusListener((status) { ? ? ? if(status == AnimationStatus.completed){ ? ? ? ? enableSlide = true; ? ? ? ? _animationController.reset(); ? ? ? } ? ? }); ? } ? }
原文鏈接:https://blog.csdn.net/yuan1809/article/details/107257581
相關推薦
- 2022-05-21 DaemonSet服務守護進程的使用場景_服務器其它
- 2021-12-03 C/C++表格組件Qt?TableWidget應用詳解_C 語言
- 2022-06-17 C語言深入講解函數參數的使用_C 語言
- 2022-11-30 react源碼層探究setState作用_React
- 2022-05-15 Python?OpenCV使用dlib進行多目標跟蹤詳解_python
- 2022-06-04 tomcat的catalina.out日志按自定義時間格式進行分割的操作方法_Tomcat
- 2022-06-11 python?針對在子文件夾中的md文檔實現批量md轉word_python
- 2022-03-31 C#值類型、引用類型、泛型、集合、調用函數的表達式樹實踐_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支