Flutter 在颤振中构建了一个计时器,但如果一个文本字段输入为空,则计时器不会启动

Flutter 在颤振中构建了一个计时器,但如果一个文本字段输入为空,则计时器不会启动,flutter,dart,Flutter,Dart,所以我做了一个定时器,它在大部分时间都能完全工作。它有启动、停止和暂停按钮,可以工作。只要我在三个文本字段(小时、分钟和秒)中的每一个字段中都输入了一些内容,启动计时器就会工作,但一旦其中一个字段没有输入(null),计时器就不会启动并吐出错误代码 用手势捕捉异常 无效数字(在字符1处) 我试着把??代码中的很多地方都有0,但我对这一点很陌生,所以这可能是一个完全愚蠢的解决方案,它不会工作 import 'package:flutter/material.dart'; import 'packa

所以我做了一个定时器,它在大部分时间都能完全工作。它有启动、停止和暂停按钮,可以工作。只要我在三个文本字段(小时、分钟和秒)中的每一个字段中都输入了一些内容,启动计时器就会工作,但一旦其中一个字段没有输入(null),计时器就不会启动并吐出错误代码

用手势捕捉异常 无效数字(在字符1处)

我试着把??代码中的很多地方都有0,但我对这一点很陌生,所以这可能是一个完全愚蠢的解决方案,它不会工作

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_plugg/main.dart';

class TimerView extends StatefulWidget {
  @override
  _TimerViewState createState() => _TimerViewState();
}


class _TimerViewState extends State<TimerView> with TickerProviderStateMixin {
  TextEditingController _minuteController  = TextEditingController();
  TextEditingController _hourController = TextEditingController();
  TextEditingController _secondController = TextEditingController();

  AnimationController _controller;

  Animation<int> _animation;

  

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _pauseTimer() {
    _controller.stop();
  }

  void _stopTimer() {
    _controller.reset();
  }

  void _startTimer() {
    int timerInput = int.parse(_hourController.text) * 3600 +
        int.parse(_minuteController.text) * 60 +
        int.parse(_secondController.text);
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: timerInput),
    );

    _animation = StepTween(begin: timerInput, end: 0).animate(_controller)
      ..addListener(() {
        _setTimerValues();
      });
    _controller.forward();
  }

  void _setTimerValues() {
    setState(() {
      print(_animation.value);
      _hourController.text = (_animation.value ~/ 3600).toString();

      _minuteController.text = ((_animation.value % 3600) ~/ 60).toString();

      _secondController.text = (_animation.value % 60).toString();
    });
  }

  Widget _textInput({TextEditingController controller}) {
    return Container(
      width: 100,
      height: 60,
      child: TextField(
        showCursor: false,
        enableInteractiveSelection: false,
        controller: controller,
        style: TextStyle(
          fontSize: 60,
        ),
        inputFormatters: [FilteringTextInputFormatter.digitsOnly],
        keyboardType: TextInputType.number,
        textAlign: TextAlign.center,
        maxLength: 2,
        decoration: InputDecoration(
          contentPadding: EdgeInsets.zero,
          hintStyle: TextStyle(color: Colors.grey),
          counterText: "",
          hintMaxLines: 1,
          hintText: "00",
          border: InputBorder.none,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: PersistentDrawer(currentPage: "Timer"),
      appBar: AppBar(
        title: Text("Timer"),
      ),
      body: Column(
        children: [
          SizedBox(height: 80),
          Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              _textInput(
                controller: _hourController,
              ),
              Text(
                "h",
                style: TextStyle(fontSize: 24),
              ),
              
              _textInput(
                controller: _minuteController,
              ),
              Text(
                "m",
                style: TextStyle(fontSize: 24),
              ),
              _textInput(controller: _secondController),
              Text(
                "s",
                style: TextStyle(fontSize: 24),
              )
            ],
          ),
          SizedBox(
            height: 60,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Padding(
                padding: const EdgeInsets.only(right: 15),
                child: ElevatedButton(
                  onPressed: () {
                    _controller?.isAnimating ?? false ? _pauseTimer() : _startTimer();
                    setState(() {});
                  },
                  child: _controller?.isAnimating ?? false
                      ? Text("Pause Timer")
                      : Text("Start Timer"),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 15),
                child: ElevatedButton(
                  onPressed: _stopTimer,
                  child: Text("Stop Timer"),),
              )
            ],
          ),
        ],
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:flifter/services.dart”;
进口“包装:flatter_plugg/main.dart”;
类TimerView扩展StatefulWidget{
@凌驾
_TimerViewState createState()=>\u TimerViewState();
}
类_TimerViewState使用TickerProviderStateMixin扩展状态{
TextEditingController _minuteController=TextEditingController();
TextEditingController\u hourController=TextEditingController();
TextEditingController_secondController=TextEditingController();
动画控制器_控制器;
动画(动画),;
@凌驾
无效处置(){
_controller.dispose();
super.dispose();
}
void_pauseTimer(){
_controller.stop();
}
void_stopTimer(){
_controller.reset();
}
void _startTimer(){
int timerInput=int.parse(_hourController.text)*3600+
int.parse(_minuteController.text)*60+
int.parse(_secondController.text);
_控制器=动画控制器(
vsync:这个,,
持续时间:持续时间(秒:timerInput),
);
_动画=StepTween(开始:timerInput,结束:0)。动画(\u控制器)
…addListener(){
_setTimerValues();
});
_controller.forward();
}
void _setTimerValues(){
设置状态(){
打印(_animation.value);
_hourController.text=(_animation.value~/3600).toString();
_minuteController.text=((_animation.value%3600)~/60).toString();
_secondController.text=(_animation.value%60).toString();
});
}
小部件_textInput({TextEditingController}){
返回容器(
宽度:100,
身高:60,
孩子:TextField(
showCursor:false,
enableInteractiveSelection:false,
控制器:控制器,
样式:TextStyle(
尺寸:60,
),
inputFormatters:[FilteringtInputFormatter.digitsOnly],
键盘类型:TextInputType.number,
textAlign:textAlign.center,
最大长度:2,
装饰:输入装饰(
contentPadding:EdgeInsets.zero,
hintStyle:TextStyle(颜色:Colors.grey),
反文本:“”,
hintMaxLines:1,
hintText:“00”,
边框:InputBorder.none,
),
),
);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
抽屉:持久抽屉(当前页:“计时器”),
appBar:appBar(
标题:文本(“计时器”),
),
正文:专栏(
儿童:[
尺寸箱(高度:80),
划船(
crossAxisAlignment:crossAxisAlignment.end,
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
_文本输入(
控制器:\ u小时控制器,
),
正文(
“h”,
样式:TextStyle(字体大小:24),
),
_文本输入(
控制器:_分钟控制器,
),
正文(
“m”,
样式:TextStyle(字体大小:24),
),
_文本输入(控制器:_secondController),
正文(
“s”,
样式:TextStyle(字体大小:24),
)
],
),
大小盒子(
身高:60,
),
划船(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
填充物(
填充:仅限常量边集(右:15),
儿童:升降按钮(
已按下:(){
_控制器?.isAnimating?false?_pauseTimer():_startTimer();
setState((){});
},
子项:_控制器?.isAnimating?错误
?文本(“暂停计时器”)
:Text(“启动计时器”),
),
),
填充物(
填充:仅限常量边集(左:15),
儿童:升降按钮(
按下按钮:\ u停止计时器,
子项:文本(“停止计时器”),),
)
],
),
],
),
);
}
}

??用于在您的案例中检查null,它是空字符串,因此请检查isNotEmpty

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_plugg/main.dart';


class TimerView extends StatefulWidget {
  @override
  _TimerViewState createState() => _TimerViewState();
}

class _TimerViewState extends State<TimerView> with TickerProviderStateMixin {
  TextEditingController _minuteController = TextEditingController();
  TextEditingController _hourController = TextEditingController();
  TextEditingController _secondController = TextEditingController();

  AnimationController _controller;

  Animation<int> _animation;

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _pauseTimer() {
    _controller.stop();
  }

  void _stopTimer() {
    _controller.reset();
  }

  void _startTimer() {
    int timerInput = int.parse(_hourController.text.isNotEmpty ? _hourController.text : '0') * 3600 +
        int.parse(_minuteController.text.isNotEmpty ? _minuteController.text : '0') * 60 +
        int.parse(_secondController.text.isNotEmpty ? _secondController.text : '0');
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: timerInput),
    );

    _animation = StepTween(begin: timerInput, end: 0).animate(_controller)
      ..addListener(() {
        _setTimerValues();
      });
    _controller.forward();
  }

  void _setTimerValues() {
    setState(() {
      print(_animation.value);
      _hourController.text = (_animation.value ~/ 3600).toString();

      _minuteController.text = ((_animation.value % 3600) ~/ 60).toString();

      _secondController.text = (_animation.value % 60).toString();
    });
  }

  Widget _textInput({TextEditingController controller}) {
    return Container(
      width: 100,
      height: 60,
      child: TextField(
        showCursor: false,
        enableInteractiveSelection: false,
        controller: controller,
        style: TextStyle(
          fontSize: 60,
        ),
        inputFormatters: [FilteringTextInputFormatter.digitsOnly],
        keyboardType: TextInputType.number,
        textAlign: TextAlign.center,
        maxLength: 2,
        decoration: InputDecoration(
          contentPadding: EdgeInsets.zero,
          hintStyle: TextStyle(color: Colors.grey),
          counterText: "",
          hintMaxLines: 1,
          hintText: "00",
          border: InputBorder.none,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: PersistentDrawer(currentPage: "Timer"),
      appBar: AppBar(
        title: Text("Timer"),
      ),
      body: Column(
        children: [
          SizedBox(height: 80),
          Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              _textInput(controller: _hourController),
              Text("h", style: TextStyle(fontSize: 24)),
              _textInput(controller: _minuteController),
              Text("m", style: TextStyle(fontSize: 24)),
              _textInput(controller: _secondController),
              Text("s", style: TextStyle(fontSize: 24))
            ],
          ),
          SizedBox(
            height: 60,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Padding(
                padding: const EdgeInsets.only(right: 15),
                child: ElevatedButton(
                  onPressed: () {
                    _controller?.isAnimating ?? false ? _pauseTimer() : _startTimer();
                    setState(() {});
                  },
                  child: _controller?.isAnimating ?? false ? Text("Pause Timer") : Text("Start Timer"),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 15),
                child: ElevatedButton(
                  onPressed: _stopTimer,
                  child: Text("Stop Timer"),
                ),
              )
            ],
          ),
        ],
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:flifter/services.dart”;
进口“包装:flatter_plugg/main.dart”;
类TimerView扩展StatefulWidget{
@凌驾
_TimerViewState createState()=>\u TimerViewState();
}
类_TimerViewState使用TickerProviderStateMixin扩展状态{
TextEditingController _minuteController=TextEditingController();
TextEditingController\u hourController=TextEditingController();
TextEditingController_secondController=TextEditingController();
动画控制器_控制器;
动画(动画),;
@凌驾
无效处置(){
_controller.dispose();
super.dispose();
}
void_pauseTimer(){
_controller.stop();
}
void_stopTimer(){
_controller.reset();
}
void _startTimer(){
int timerInput=int.parse(\u hourController.text.isNotEmpty?\u hourController.text:'0')*3600+
int.parse(_minuteController.text.isNotEmpty?_minuteController.text:'0')*60+
int.parse(_secondController.text.isNotEmpty?_secondController.text:'0');
_控制
String _format(value) {
    if (value != null && value.isNotEmpty) {
        return value;
    }
    return "0";
}
void _startTimer() {
    int timerInput = int.parse(_format(_hourController.text)) * 3600 +
        int.parse(_format(_minuteController.text)) * 60 +
        int.parse(_format(_secondController.text));
    _controller = AnimationController(
        vsync: this,
        duration: Duration(seconds: timerInput),
    );

    _animation = StepTween(begin: timerInput, end: 0).animate(_controller)
        ..addListener(() {
            _setTimerValues();
        });
    _controller.forward();
}