溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Flutter怎么實現(xiàn)滑動塊驗證碼功能

發(fā)布時間:2022-03-24 09:16:05 來源:億速云 閱讀:397 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Flutter怎么實現(xiàn)滑動塊驗證碼功能”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Flutter怎么實現(xiàn)滑動塊驗證碼功能”文章能幫助大家解決問題。

本文實現(xiàn)的是一個用于登錄時,向右滑動滑動塊到最右邊完成驗證的一個功能。當(dāng)滑動未到最右邊時,滑動塊回彈回左邊起始位置。

Flutter怎么實現(xiàn)滑動塊驗證碼功能

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
  State<StatefulWidget> createState() {
    return SlideVerifyState();
  }
 
}
 
class SlideVerifyState extends State<SlideVerifyWidget> 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;
        }
        /// 當(dāng)滑動到最右邊時,通知驗證成功,并禁止滑動
        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),
            /// 圓角實現(xiàn)
          borderRadius: BorderRadius.all(new Radius.circular(height))
        ),
        child: Stack(
          children: <Widget>[
            Positioned(
              top: 0,
              left: 0,
              child: Container(
                height: height - 2,
                /// 當(dāng)slider滑動到距左邊只有兩三像素距離時,已滑動背景會有一點點渲染出邊框范圍,
                /// 因此當(dāng)滑動距離小于1時,直接將寬度設(shè)置為0,解決滑動塊返回左邊時導(dǎo)致的綠色閃動,但如果是緩慢滑動到左邊該問題仍沒解決
                width: sliderDistance < 1? 0 : sliderDistance + sliderWidth / 2,
                decoration: BoxDecoration(
                    color: widget.slideColor,
                    /// 圓角實現(xiàn)
                    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是解決當(dāng)滑動塊滑動到最右邊時遮擋外部邊框
              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),
                    /// 圓角實現(xiàn)
                    borderRadius: BorderRadius.all(new Radius.circular(height))
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    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,),
                    /// 因為向右箭頭有透明邊距導(dǎo)致兩個箭頭間隔過大,因此將第二個箭頭向左偏移,如果切圖無邊距則不用偏移
                    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();
      }
    });
  }
 
}

關(guān)于“Flutter怎么實現(xiàn)滑動塊驗證碼功能”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI