2017-06-01 48 views
1

我正在嘗試構建倒計時部件。目前,我得到了結構工作。我只爲倒計時本身而奮鬥。我使用倒計時插件嘗試了這種方法:顫振 - 創建倒計時部件

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

你是什麼意思怪異?你需要動畫嗎? –

回答

5

聽起來好像您正在嘗試顯示隨時間變化的動畫文本小部件。我會使用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

1

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

好點,只是想顯示原始問題。 –