如何修复Flutter中长按倒计时?

问题描述 投票:0回答:2

我正在尝试实现该按钮,长按时需要屏住呼吸 10 秒,对于用户我想显示还剩多少秒,但当前的实现编号在长按时是静态的,我无法获取为什么,因为onLongPress内部调用了函数并取消了onLongPressEnd。

      late Timer ?timer;
      int _counter = 10;
      void startTimer() {
      const oneSec = const Duration(seconds: 10);
      timer = new Timer.periodic(
      oneSec,
      (Timer ?timer) {
      if (_counter == 0) {
      setState(() {
         timer?.cancel();
      });
      } else {
        setState(() {
        _counter--;
        });
      }
      },
      );

      OnLongPress implementation
      onLongPress: () {
      startTimer(); 
      setState(() {
        _counter;}
      onLongPressEnd: (details) {
          timer?.cancel();
      setState(() {
      _isLongPressActivated = false;
      }, 

非常感谢您的帮助

flutter counter
2个回答
0
投票

您发布的代码可能存在多个问题,但我获取了您的代码,这是一个基于入门应用程序的工作代码:

import 'dart:async';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  static const String _title = 'Flutter Stateful Clicker Counter';
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ValueNotifier<int> _counter = ValueNotifier(10);

  late Timer? timer;

  final oneSec = const Duration(seconds: 1);

  void tickCounter() {
    print("ticking counter ${_counter.value}");
    if (_counter.value <= 0) {
      cancelTimer();
      return;
    }
    _counter.value = _counter.value - 1;
  }

  void startTimer() {
    timer = Timer.periodic(
      oneSec,
      (Timer? timer) {
        tickCounter();
      },
    );
  }

  void cancelTimer() {
    timer?.cancel();
  }

  void onLongPressStarted() {
    print("Long press started");
    startTimer();
  }

  void onLongPressCanceled() {
    print("Long press ended");
    cancelTimer();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Demo Click Counter'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            GestureDetector(
                onLongPress: onLongPressStarted,
                onLongPressCancel: onLongPressCanceled,
                child: Container(
                  child: Text("Hold Me"),
                )),
            ValueListenableBuilder(
                valueListenable: _counter,
                builder: (context, value, child) => Text(
                      value.toString(),
                      style: const TextStyle(fontSize: 25),
                    )),
          ],
        ),
      ),
    );
  }
}


0
投票

GestureDetecture
onTapDown
onTapUp
是您需要实现的正确回调。

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
 
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
 
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 10;
 
  Timer? _timer;
 
  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }
 
  void _startTimer() {
    _timer?.cancel();
    _timer = Timer.periodic(
      const Duration(seconds: 1),
      (Timer? timer) {
        if (_counter <= 0) {
          return;
        }
        setState(() {
          _counter--;
        });
      },
    );
  }
 
  void _resetTimer() {
    _timer?.cancel();
    setState(() {
      _counter = 10;
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            GestureDetector(
              onTapDown: (_) => _startTimer(),
              onTapUp: (_) => _resetTimer(),
              child: const ColoredBox(
                color: Colors.cyan,
                child: Text(
                  'Press and hold',
                ),
              ),
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.