Dart 颤振应用程序冻结并不运行';I don’我没有按预期工作

Dart 颤振应用程序冻结并不运行';I don’我没有按预期工作,dart,flutter,Dart,Flutter,我有一个颤振应用程序,有2页。第一页是一个简单的墨水池,它将用户发送到第2页。点击第2页时,计时器应每秒递减一次。它不会启动增量,而是冻结 import 'package:flutter/material.dart'; import 'dart:io'; int _time = 60; bool _restart = false; class MainPage extends StatefulWidget { @override MainPageState createState(

我有一个颤振应用程序,有2页。第一页是一个简单的墨水池,它将用户发送到第2页。点击第2页时,计时器应每秒递减一次。它不会启动增量,而是冻结

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


int _time = 60;
bool _restart = false;

class MainPage extends StatefulWidget {
  @override
  MainPageState createState() => new MainPageState();
}

class MainPageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) {
      return new Material(
      color: Colors.greenAccent,
      child: new InkWell(
        onTap: () {
          setState((){
            while ( true ) {
              sleep(const Duration(seconds:1));
              _time = _time - 1;
            }
          });
        },
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(_time.toString(), style: new TextStyle(color:             
Colors.white, fontSize: 60.0, fontWeight: FontWeight.bold)),          
          ]
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“dart:io”;
int_时间=60;
bool _restart=false;
类MainPage扩展了StatefulWidget{
@凌驾
MainPageState createState()=>新建MainPageState();
}
类MainPageState扩展状态{
@凌驾
小部件构建(构建上下文){
退回新材料(
颜色:Colors.greenAccent,
孩子:新墨水井(
onTap:(){
设置状态(){
while(true){
睡眠(持续时间(秒:1));
_时间=_时间-1;
}
});
},
子:新列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
新文本(_time.toString(),样式:新文本样式(颜色:
颜色。白色,字体大小:60.0,字体重量:字体重量。粗体),
]
),
),
);
}
}

这是因为您处于无限循环中,更好的方法是使用计时器:

  class TimerSample extends StatefulWidget {
    @override
    _TimerSampleState createState() => _TimerSampleState();
  }

  class _TimerSampleState extends State<TimerSample> {
    int _time = 60;
    bool _restart = false;
    Timer timer;

    _onTap() {
      if (timer == null) {
        timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
          _time = _time - 1;

          //your conditions here
          //call setState if you want to refresh the content
        });
      }
    }

    @override
    void dispose() {
      if (timer != null) {
        timer.cancel();
      }
      super.dispose();
    }

    @override
    Widget build(BuildContext context) {
      return new Material(
        color: Colors.greenAccent,
        child: new InkWell(
          onTap: _onTap,
          child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(_time.toString(),
                    style: new TextStyle(
                        color: Colors.white,
                        fontSize: 60.0,
                        fontWeight: FontWeight.bold)),
              ]),
        ),
      );
    }
  }
class TimerSample扩展StatefulWidget{
@凌驾
_TimerSampleState createState()=>\u TimerSampleState();
}
类\u TimerSampleState扩展状态{
int_时间=60;
bool _restart=false;
定时器;
_onTap(){
如果(计时器==null){
计时器=计时器。周期性(持续时间(秒:1),(计时器t){
_时间=_时间-1;
//你在这里的条件
//如果要刷新内容,请调用setState
});
}
}
@凌驾
无效处置(){
如果(计时器!=null){
timer.cancel();
}
super.dispose();
}
@凌驾
小部件构建(构建上下文){
退回新材料(
颜色:Colors.greenAccent,
孩子:新墨水井(
onTap:_onTap,
子:新列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
新文本(_time.toString(),
样式:新文本样式(
颜色:颜色,白色,
字体大小:60.0,
fontWeight:fontWeight.bold),
]),
),
);
}
}

这是因为您处于无限循环中,更好的方法是使用计时器:

  class TimerSample extends StatefulWidget {
    @override
    _TimerSampleState createState() => _TimerSampleState();
  }

  class _TimerSampleState extends State<TimerSample> {
    int _time = 60;
    bool _restart = false;
    Timer timer;

    _onTap() {
      if (timer == null) {
        timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
          _time = _time - 1;

          //your conditions here
          //call setState if you want to refresh the content
        });
      }
    }

    @override
    void dispose() {
      if (timer != null) {
        timer.cancel();
      }
      super.dispose();
    }

    @override
    Widget build(BuildContext context) {
      return new Material(
        color: Colors.greenAccent,
        child: new InkWell(
          onTap: _onTap,
          child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(_time.toString(),
                    style: new TextStyle(
                        color: Colors.white,
                        fontSize: 60.0,
                        fontWeight: FontWeight.bold)),
              ]),
        ),
      );
    }
  }
class TimerSample扩展StatefulWidget{
@凌驾
_TimerSampleState createState()=>\u TimerSampleState();
}
类\u TimerSampleState扩展状态{
int_时间=60;
bool _restart=false;
定时器;
_onTap(){
如果(计时器==null){
计时器=计时器。周期性(持续时间(秒:1),(计时器t){
_时间=_时间-1;
//你在这里的条件
//如果要刷新内容,请调用setState
});
}
}
@凌驾
无效处置(){
如果(计时器!=null){
timer.cancel();
}
super.dispose();
}
@凌驾
小部件构建(构建上下文){
退回新材料(
颜色:Colors.greenAccent,
孩子:新墨水井(
onTap:_onTap,
子:新列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
新文本(_time.toString(),
样式:新文本样式(
颜色:颜色,白色,
字体大小:60.0,
fontWeight:fontWeight.bold),
]),
),
);
}
}

来自睡眠文档

请小心使用,因为在睡眠调用中被阻止时,隔离中不能处理任何异步操作

您不应该在setState中有逻辑,它应该仅用于更改值

据我所知,您希望启动一个计时器,每秒钟更新一次ui

我会那样做的

Timer _timer;

...
_timer ??= new Timer.periodic(const Duration(seconds:1), () {
    setState(() {
      _time = _time - 1;
    });
 })

...
dispose() {
  super.dispose();
  _timer?.cancel();
}

来自睡眠文档

请小心使用,因为在睡眠调用中被阻止时,隔离中不能处理任何异步操作

您不应该在setState中有逻辑,它应该仅用于更改值

据我所知,您希望启动一个计时器,每秒钟更新一次ui

我会那样做的

Timer _timer;

...
_timer ??= new Timer.periodic(const Duration(seconds:1), () {
    setState(() {
      _time = _time - 1;
    });
 })

...
dispose() {
  super.dispose();
  _timer?.cancel();
}

使用
AnimatedBuilder
可以避免调用
setState
来更新计数器文本。否则,您可能会为了更新动画而不必要地重建小部件

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  int _startTime = 10;
  Duration _totalTime;
  AnimationController _controller;

  @override
  void initState() {
    _totalTime = Duration(seconds: _startTime);
    _controller = AnimationController(
      vsync: this,
      duration: _totalTime,
    );
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.greenAccent,
      child: InkWell(
        onTap: () {
          if (_timeLeft().inMicroseconds == 0) {
            _controller.reset();
          } else {
            if (!_controller.isAnimating) {
              _controller.forward();
            } else {
              _controller.stop(canceled: false);
            }
          }
        },
        child: AnimatedBuilder(
          animation: _controller,
          builder: (BuildContext context, Widget child) {
            return Center(
                child: Text(
              '${_timeLeft().inSeconds}',
              style: TextStyle(
                fontSize: 60.0,
                color: Colors.white,
                fontWeight: FontWeight.bold,
              ),
            ));
          },
        ),
      ),
    );
  }

  Duration _timeLeft() {
    final timeLeft = _totalTime - (_totalTime * _controller.value);
    if (timeLeft.inMicroseconds == 0 || timeLeft == _totalTime) {
      return timeLeft;
    } else {
      return timeLeft + const Duration(seconds: 1);
    }
  }
}
class\u MyHomePageState使用TickerProviderStateMixin扩展状态{
int_startTime=10;
持续时间_总时间;
动画控制器_控制器;
@凌驾
void initState(){
_总时间=持续时间(秒:_startTime);
_控制器=动画控制器(
vsync:这个,,
持续时间:_总时间,
);
super.initState();
}
@凌驾
无效处置(){
super.dispose();
_controller.dispose();
}
@凌驾
小部件构建(构建上下文){
退货(
颜色:Colors.greenAccent,
孩子:InkWell(
onTap:(){
如果(_timeLeft().inMicroseconds==0){
_controller.reset();
}否则{
如果(!\u控制器正在初始化){
_controller.forward();
}否则{
_控制器。停止(取消:假);
}
}
},
子对象:动画生成器(
动画:_控制器,
生成器:(BuildContext上下文,小部件子项){
返回中心(
子:文本(
“${u timeLeft().unseconds}”,
样式:TextStyle(
字体大小:60.0,
颜色:颜色,白色,
fontWeight:fontWeight.bold,
),
));
},
),
),
);
}
持续时间