【问题标题】:How to keep changing a Images every 5 seconds in Flutter?如何在 Flutter 中保持每 5 秒更改一次图像?
【发布时间】:2018-03-23 08:01:32
【问题描述】:

状态变量:

var moviePhotos = [
"http://www.kiwithebeauty.com/wp-content/uploads/2017/11/BLACK-PANTHER-COLLAGE-KIWI-THE-BEAUTY-MOVIE-MARVEL-800x350.png",
"https://static-ssl.businessinsider.com/image/5a7085a97e7a35f10c8b479f-1000/blackpanthershuri.jpg",
"https://longreadsblog.files.wordpress.com/2018/02/black-panther.jpg?w=1680",
"https://uziiw38pmyg1ai60732c4011-wpengine.netdna-ssl.com/wp-content/dropzone/2018/02/black-panther.jpg",
"https://static2.srcdn.com/wp-content/uploads/2017/10/Black-Panther-Trailer-1.jpg?q=50&w=1000&h=500&fit=crop&dpr=1.5",
"https://cdn.guidingtech.com/imager/media/assets/BP-2_acdb3e4bb37d0e3bcc26c97591d3dd6b.jpg",
"https://cdn.guidingtech.com/imager/media/assets/BP-8_acdb3e4bb37d0e3bcc26c97591d3dd6b.jpg"
];
var bannerPosition = 0;

我希望下面的函数每 5 秒通过递增bannerPosition 更改数组中的位置,以便在应用程序上呈现新图像

testing() async {
    while(true){
        await new Future.delayed(const Duration(seconds : 5));
            if (bannerPosition < moviePhotos.length){
                print("Banner Position Pre");
                print(bannerPosition);
                setState(() {
                    bannerPosition = bannerPosition + 1;
                });
                print("Banner Position Post");
                print(bannerPosition);                      
            }                   
            else{
                setState(() {
                    bannerPosition = 0;
                });                     
            }       
        }

}

当我执行此代码时,“Future.delayed(const Duration(seconds : 5))”不会以有序的方式发生,它会导致图像渲染问题。

【问题讨论】:

    标签: asynchronous flutter


    【解决方案1】:

    我不知道您所说的“没有以有序的方式发生”是什么意思。虽然只是看着它,但我认为它会起作用,只是我似乎记得在循环中使用 await 有一些奇怪的地方。它可能会不断循环并创建越来越多的对延迟的调用......

    改为使用Timer。这样它处理循环。我还建议保存对计时器的引用并在您所在州的 dispose() 函数中停止它。

    这是一个代码示例:

    class ImageRotater extends StatefulWidget {
      List<String> photos;
    
      ImageRotater(this.photos);
    
      @override
      State<StatefulWidget> createState() => new ImageRotaterState();
    }
    
    class ImageRotaterState extends State<ImageRotater> {
      int _pos = 0;
      Timer _timer;
    
      @override
      void initState() {
        _timer = Timer.periodic(new Duration(seconds: 5), () {
          setState(() {
            _pos = (_pos + 1) % widget.photos.length;
          });
        });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Image.network(
          widget.photos[_pos],
          gaplessPlayback: true,
        );
      }
    
      @override
      void dispose() {
        _timer.cancel();
        _timer = null;
        super.dispose();
      }
    }
    

    请注意,第一次浏览照片时仍可能存在一些不一致之处,因为它只是在加载照片时进行。 'gaplessPlayback' 标志应该使前一个图像一直存在,直到新图像完全加载为止。

    【讨论】:

    • 我所说的“没有以有序的方式发生”的意思是,我的 testing() 函数中的循环每次都没有统一延迟 5 秒。因此,我的变量 bannerPosition 不会每 5 秒更改一次(而是在某种随机时间跨度内发生 - 在 2 到 6 秒之间)。因此,我的图像在一种随机的时间范围内不断变化。你能帮我实现一个确保bannerPosition每5秒周期性变化的功能吗?
    • 好的,正如我所说,计时器是定期更改的最佳工具。我已经更新了一个代码示例。
    • 如果上面的代码不起作用,请使用它。常量 oneSec = 常量持续时间(秒:5); _timer = new Timer.periodic( oneSec, (Timer timer) => setState( () { _pos = (_pos + 1); // }, ), );
    • 很好的例子@rmtmckenzie
    【解决方案2】:

    改进“rmtmckenzie”答案,如果您想每 5 秒重复一次,则需要使用 Timer.periodic。见下文

      @override
      void initState() {
        _timer = Timer.periodic(Duration(seconds: 5), (Timer t) {
          setState(() {
            _pos = (_pos + 1) % widget.photos.length;
          });
        });
        super.initState();
      }
    

    【讨论】:

      猜你喜欢
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多