基于保持的循环进度按钮(颤振)

ali*_*ali 2 dart flutter

我正在尝试创建一个按钮,当用户按住该按钮时会有一个进度,但是如果用户在完成按钮之前未按下按钮,则进度会减少。像图片上的东西在此处输入图片说明

Nik*_*las 6

正如Arnold Parge所说,您可以使用GestureDetector并收听onTapDownonTapUp。要创建所需的LoadingButton,可以使用以下窗口小部件结构:

- GetureDetector
  - Stack
    - CircularProgressIndicator // background circle
    - CircularProgressIndicator // foreground circle
    - Icon
Run Code Online (Sandbox Code Playgroud)

要创建动画,您可以添加AnimationController并将前景的值绑定CircularProgressIndicatorAnimationController.value。现在,您只需将两个侦听器添加到中GestureDetector

  • onTapDown:点击按钮时,动画应该开始。因此,我们称AnimationController.forward()
  • onTapUp:释放新闻时,我们要检查动画是否已经完成。我们可以使用AnimationController.status来检查状态。如果是,AnimationStatus.forward它仍在运行。因此,我们想通过调用来反转动画AnimationController.reverse()

这是结果按钮:

按钮动画

以及完整的源代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: Scaffold(
        body: Center(child: LoadingButton()),
      ),
    );
  }
}

class LoadingButton extends StatefulWidget {
  @override
  LoadingButtonState createState() => LoadingButtonState();
}

class LoadingButtonState extends State<LoadingButton>
    with SingleTickerProviderStateMixin {
  AnimationController controller;

  @override
  void initState() {
    super.initState();

    controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));
    controller.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) => controller.forward(),
      onTapUp: (_) {
        if (controller.status == AnimationStatus.forward) {
          controller.reverse();
        }
      },
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          CircularProgressIndicator(
            value: 1.0,
            valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
          ),
          CircularProgressIndicator(
            value: controller.value,
            valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
          ),
          Icon(Icons.add)
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)