【问题标题】:flutter show images (assets) in rapid succession快速连续显示图像(资产)
【发布时间】:2021-04-04 00:32:58
【问题描述】:

我的 Flutter 应用程序的一部分有一个过滤器功能,用于过滤项目列表。作为 UX 的一部分,应该向用户指示当前操作。

问题我面临的是显示当前正在过滤(评估)的项目 - 图像根本不会显示或将“卡住” 1 - 原因很可能是运行循环将状态设置得太快,无法进行重绘。

这是我想要完成的一个粗略示例

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int i = 0;
  List<String> _images = [
    "assets/sample/sample1.jpg",
    "assets/sample/sample2.jpg",
    "assets/sample/sample3.jpg",
    "assets/sample/sample4.jpg",
  ];

  @override
  void initState() {
    super.initState();
    Timer(Duration(), () {
      while (true) {
        i++;
        setState(() {
          i = i % 4;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    Widget content = Container(
        child: ClipRRect(
      clipBehavior: Clip.antiAlias,
      child: CircleAvatar(
        radius: 24,
        backgroundColor: Colors.transparent,
        child: Image.asset(_images[i], gaplessPlayback: true,),
      ),
    ));

    return MaterialApp(
      home: Scaffold(
        body: content,
      ),
    );
  }

问题:

为了简化事情,我怎样才能快速(并重复地)显示几张图像,即 1、2、3、4、1、2、3...之间(最多)有几毫秒的延迟?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    不要使用while循环,因为会阻塞线程,不让其他任务执行

    你可以使用 Timer.periodic 之类的东西,它让你可以选择控制图像应该改变的帧速率

    也不要使用 setState,因为它会导致整个小部件重新构建,您可以使用 ValueNotifer 直接通知特定小部件的更改

    还记得在你的小部件被释放时取消计时器

    这里是例子

    class _PageAState extends State<PageA> {
      ValueNotifier<String> currentImage = ValueNotifier("0.png");
      int counter=0;
      Timer imageTimer;
    
      @override
      void initState() {
        super.initState();
        this.imageTimer=Timer.periodic(Duration(milliseconds: 100), (timer) {
          counter++;
          currentImage.value="${counter%3}.png";
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return ValueListenableBuilder<String>(
          valueListenable: currentImage,
          builder: (context, value, child) {
            return Image.asset(
              value,
              width: 30,
              height: 30,
              color: Colors.red,
            );
          },
        );
      }
    
      @override
      void dispose() {
        super.dispose();
        if(imageTimer!=null)imageTimer.cancel();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-14
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-31
      相关资源
      最近更新 更多