【问题标题】:How to load stateful widget in the background如何在后台加载有状态的小部件
【发布时间】:2021-07-14 21:54:06
【问题描述】:

我有一个有状态的小部件,它每 10 秒更改一次背景图像,我注意到每次更改背景图像时它都会闪烁。

它循环显示用于背景的图像列表。

当它到达列表末尾并返回加载第一张图像时,它不会再闪烁了。

我对此进行了一些谷歌搜索,闪烁是由在 setState 中重建整个小部件引起的。

但是,在它加载了所有可能的带有不同图像的小部件后,它不会闪烁。

我的假设是,它将先前的小部件存储在缓存中,或者将找出在先前的 setState 中发生了什么变化,因此它不会闪烁,因为它只知道更改背景。

我不确定这是否正确。

我的问题是,您如何加载多个小部件但不将它们显示在屏幕和背景中。

所以基本上在 10 秒内从第一个背景图像切换到第二个。

会有一个 Future 加载所有不同的可能背景图像。

提前致谢!

编辑:(复制问题的代码)

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Title',
      theme: ThemeData(
        backgroundColor: Colors.white,
        primarySwatch: Colors.blue,
      ),
      home: MyHome(),
    );
  }
}

class MyHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ImageRotater(
      child: Text("Some text"),
    );
  }
}

class ImageRotater extends StatefulWidget {
  final Widget child;

  ImageRotater({required this.child});

  @override
  _ImageRotaterState createState() => _ImageRotaterState();
}

class _ImageRotaterState extends State<ImageRotater>
    with TickerProviderStateMixin {
  late final subtree;

  static List<String> imageNames = [
    "1.png",
    "2.png",
    "3.png",
  ];

  int _pos = 0;
  late Timer _timer;

  late AnimationController _animationController;

  @override
  void initState() {
    subtree = this.widget.child;
    //Setting up Animation

    _animationController = AnimationController(
      vsync: this,
      duration: Duration(seconds: 3),
      upperBound: 255.0,
      lowerBound: 0.0,
      value: 255.0,
    );

    _animationController.reverse();

    //Setting up Timer for Casaroul
    _timer = Timer.periodic(Duration(seconds: 10), (timer) async {
      _animationController.forward();

      await Future.delayed(Duration(milliseconds: 3000)).then((_) {
        setState(() {
          _pos = (_pos + 1) % imageNames.length;
        });
        _animationController.reverse();
      });
    });

    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return AnimatedBuilder(
        animation: _animationController,
        builder: (BuildContext context, _) {
          return Container(
            width: size.width,
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage("images/" + imageNames[_pos]),
                alignment: Alignment.centerLeft,
                fit: BoxFit.cover,
                colorFilter: ColorFilter.mode(
                  Colors.black.withAlpha(_animationController.value.toInt()),
                  BlendMode.multiply,
                ),
              ),
            ),
            child: subtree,
          );
        });
  }
}

这是一些代码,

如果您尝试任何 3 张图片,您会注意到闪烁来自

Img 1 -> Img 2

Img 2 -> Img 3

但是从,

Img 3 -> Img 1

以后,所有的过渡都不会闪烁。

【问题讨论】:

  • 解决方案的最小代码示例会有所帮助
  • 我添加了示例代码

标签: flutter


【解决方案1】:

我认为达到你想要的正确方法是使用 bloc 模式Bloc library

使用这种模式,您可以将状态与 ui 分开,并且您可以轻松地在应用中的任何位置管理状态

【讨论】:

    【解决方案2】:

    所以我正在寻找的技术术语是“预加载图像”。

    我找到了一个完全符合我要求的帖子,它解决了闪烁问题。

    这是链接:

    Flutter Preloading

    【讨论】:

      猜你喜欢
      • 2020-02-11
      • 2020-04-25
      • 2021-02-16
      • 2021-09-21
      • 2021-12-24
      • 2021-05-19
      • 2019-10-06
      • 2021-07-25
      • 2019-10-06
      相关资源
      最近更新 更多