颤振 - 创建倒计时部件

问题描述:

我正在尝试构建倒计时部件。目前,我得到了结构工作。我只为倒计时本身而奋斗。我使用倒计时插件尝试了这种方法:颤振 - 创建倒计时部件

class _Countdown extends State<Countdown> { 

    int val = 3; 

    void countdown(){ 
    CountDown cd = new CountDown(new Duration(seconds: 4)); 

    cd.stream.listen((Duration d) { 
     setState((){ 
     val = d.inSeconds; 
     }); 
    }); 

    } 

    @override 
    build(BuildContext context){ 
    countdown(); 
    return new Scaffold(
     body: new Container(
     child: new Center(
      child: new Text(val.toString(), style: new TextStyle(fontSize: 150.0)), 
     ), 
    ), 
    ); 
    } 
} 

但是,值的变化非常奇怪,而且根本不平滑。它开始抽搐。任何其他方法或修复?

+0

你能对你的时刻,详细点吗?你的代码看起来如何? –

+0

其实,我得到了工作的结构。唯一的问题是功能本身。我用Timer和countdown.dart插件试了一下。我会分享我的代码 – OhMad

+0

你是什么意思怪异?你需要动画吗? –

听起来好像您正在尝试显示随时间变化的动画文本小部件。我会使用AnimatedWidgetStepTween来确保倒数只显示整数值。

countdown

import 'package:flutter/material.dart'; 

void main() { 
    runApp(new MaterialApp(
    home: new MyApp(), 
)); 
} 

class Countdown extends AnimatedWidget { 
    Countdown({ Key key, this.animation }) : super(key: key, listenable: animation); 
    Animation<int> animation; 

    @override 
    build(BuildContext context){ 
    return new Text(
     animation.value.toString(), 
     style: new TextStyle(fontSize: 150.0), 
    ); 
    } 
} 

class MyApp extends StatefulWidget { 
    State createState() => new _MyAppState(); 
} 

class _MyAppState extends State<MyApp> with TickerProviderStateMixin { 
    AnimationController _controller; 

    static const int kStartValue = 4; 

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

    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     floatingActionButton: new FloatingActionButton(
     child: new Icon(Icons.play_arrow), 
     onPressed:() => _controller.forward(from: 0.0), 
    ), 
     body: new Container(
     child: new Center(
      child: new Countdown(
      animation: new StepTween(
       begin: kStartValue, 
       end: 0, 
      ).animate(_controller), 
     ), 
     ), 
    ), 
    ); 
    } 
} 
+0

感谢Collin,从阅读代码我猜动画只要按下按钮就会播放,对吧?一旦实例化类,我该如何让它发挥作用? – OhMad

+0

您可以在initState()中调用_controller.forward()。 –

+0

谢谢,有道理:) – OhMad

countdown()方法应该从State对象的initState()方法被调用。从Flutter docsinitState()

class _CountdownState extends State<CountdownWidget> { 

    int val = 3; 
    CountDown cd; 

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

说明:

框架调用INITSTATE。 State的子类应该重写 initState以执行一次性初始化,这取决于 BuildContext或小部件,这些小部件在调用initState方法时分别作为上下文和 小部件属性提供。

这是一个完整的工作示例:

import 'dart:async'; 
import 'package:flutter/material.dart'; 
import 'package:countdown/countdown.dart'; 

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

class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'Countdown Demo', 
     theme: new ThemeData(
     primarySwatch: Colors.blue, 
    ), 
     home: new MyHomePage(), 
    ); 
    } 
} 


class MyHomePage extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new CountdownWidget(); 
    } 
} 

class _CountdownState extends State<CountdownWidget> { 

    int val = 3; 
    CountDown cd; 

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

    void countdown(){ 
    print("countdown() called"); 
    cd = new CountDown(new Duration(seconds: 4)); 
    StreamSubscription sub = cd.stream.listen(null); 
    sub.onDone(() { 
     print("Done"); 
    }); 
    sub.onData((Duration d) { 
     if (val == d.inSeconds) return; 
     print("onData: d.inSeconds=${d.inSeconds}"); 
     setState((){ 
     val = d.inSeconds; 
     }); 
    }); 
    } 

    @override 
    build(BuildContext context){ 
    return new Scaffold(
     body: new Container(
     child: new Center(
      child: new Text(val.toString(), style: new TextStyle(fontSize: 150.0)), 
     ), 
    ), 
    ); 
    } 
} 

class CountdownWidget extends StatefulWidget { 

    @override 
    _CountdownState createState() => new _CountdownState(); 
} 
+0

如果状态在倒计时运行时处理,此代码将抛出错误。在Flutter中,最好在收听流时总是使用StreamBuilder,而不是调用setState() –

+0

好点,只是想显示原始问题。 –