You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现Card点击暂停/恢复、双击重置倒计时功能

解决neon_circular_timer控制器为空及Card点击控制倒计时的问题

问题核心错误点

  1. 控制器定义无效:原代码中your_controller返回的是00,并非有效的CountDownController实例,导致调用方法时返回null
  2. 状态管理缺失:Pads是无状态组件,无法维护计时器的状态变化,需要改为有状态组件
  3. 点击事件未完整实现:第二个Card未添加点击监听,且未实现暂停/恢复的切换逻辑与双击重置功能
  4. 控制器复用冲突:两个计时器共用无效的控制器,无法独立控制

解决方案步骤

  • 将Pads改为StatefulWidget,用于维护两个独立的CountDownController实例
  • 为每个Card添加InkWell包裹,实现单击切换暂停/恢复、双击重置的逻辑
  • 通过controller.isPaused判断当前计时器状态,实现暂停与恢复的切换
  • 为每个NeonCircularTimer绑定对应的独立控制器

修复后的完整代码

import 'package:flutter/material.dart';
import 'package:neon_circular_timer/neon_circular_timer.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.teal,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const Pads(),
    );
  }
}

class Pads extends StatefulWidget {
  const Pads({super.key});

  @override
  State<Pads> createState() => _PadsState();
}

class _PadsState extends State<Pads> {
  // 为两个计时器创建独立的控制器
  final CountDownController _blueTimerController = CountDownController();
  final CountDownController _greenTimerController = CountDownController();

  // 切换暂停/恢复的通用方法
  void _togglePauseResume(CountDownController controller) {
    if (controller.isPaused) {
      controller.resume();
    } else {
      controller.pause();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('CHESS APP'),
        leading: const Icon(Icons.image_aspect_ratio),
        toolbarHeight: 50,
      ),
      body: Column(children: <Widget>[
        SizedBox(
          height: 360,
          width: 500,
          child: InkWell(
            onTap: () => _togglePauseResume(_blueTimerController),
            onDoubleTap: () => _blueTimerController.reset(),
            child: Card(
              elevation: 20,
              shadowColor: Colors.blueGrey,
              color: Colors.blueAccent,
              margin: const EdgeInsets.all(10),
              shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(10))),
              clipBehavior: Clip.hardEdge,
              child: NeonCircularTimer(
                width: 200,
                duration: 300,
                isReverse: true,
                isReverseAnimation: true,
                controller: _blueTimerController,
                isTimerTextShown: true,
                neumorphicEffect: true,
                innerFillColor: Colors.black12,
                backgroudColor: Colors.blueAccent,
                innerFillGradient: LinearGradient(colors: [
                  Colors.greenAccent.shade200,
                  Colors.blueAccent.shade400
                ]),
                neonGradient: LinearGradient(colors: [
                  Colors.greenAccent.shade200,
                  Colors.blueAccent.shade400
                ]),
              ),
            ),
          ),
        ),
        SizedBox(
          height: 360,
          width: 500,
          child: InkWell(
            onTap: () => _togglePauseResume(_greenTimerController),
            onDoubleTap: () => _greenTimerController.reset(),
            child: Card(
              elevation: 20,
              shadowColor: Colors.blueGrey,
              color: Colors.green,
              margin: const EdgeInsets.all(10),
              shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(10))),
              clipBehavior: Clip.hardEdge,
              child: NeonCircularTimer(
                width: 200,
                duration: 300,
                isReverse: true,
                isReverseAnimation: true,
                controller: _greenTimerController,
                isTimerTextShown: true,
                neumorphicEffect: true,
                innerFillColor: Colors.black12,
                backgroudColor: Colors.green,
                innerFillGradient: LinearGradient(colors: [
                  Colors.greenAccent.shade200,
                  Colors.blueAccent.shade400
                ]),
                neonGradient: LinearGradient(colors: [
                  Colors.greenAccent.shade200,
                  Colors.blueAccent.shade400
                ]),
              ),
            ),
          ),
        )
      ]),
    );
  }
}

关键修改说明

  • 状态组件转换:Pads改为StatefulWidget,可以在状态类中创建并维护控制器实例
  • 独立控制器:为两个计时器分别创建_blueTimerController和_greenTimerController,避免操作互相影响
  • 点击逻辑实现:
    • 单击通过_togglePauseResume方法,根据controller.isPaused状态切换暂停/恢复
    • 双击直接调用controller.reset()实现重置
  • InkWell包裹:每个Card都用InkWell包裹,解决Card只能有一个child的问题,同时添加点击事件监听

内容的提问来源于stack exchange,提问作者Atharv More

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:50:10