image - 重绘图像时出现白色闪烁 [ flutter ​​]

标签 image flutter flutter-desktop flutter-image

我正在尝试构建一个具有给定宽度和高度的图像网格,将它们包裹在 Containers 内并使用 fit: BoxFit.fill如果选择了图像,则能够设置边框(我不在乎保持图像的纵横比,我希望每个容器的总宽度和高度相同)。

问题是当图像被点击后重新绘制时,我注意到一个白色的闪光。
当图像很少时,这似乎不会发生,但是对于 15 个以上的图像,它很嘈杂。

我尝试添加 gaplessPlayback: true在图像小部件上,我发现 here ,但这并没有解决我的问题。

这是一个显示我的问题的 gif(我使用了 16 张图像,大小为 1920x1080):

编辑:

我忘了指出这只是一个例子,我在代码中使用了边框,但在我的情况下,我还想向容器添加填充以使图像更小(如在 android 照片库中),这意味着每次点击的图像都应该重新绘制。

enter image description here

这是我的代码:

import 'dart:io';

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

void main() {
  // See https://github.com/flutter/flutter/wiki/Desktop-shells#target-platform-override
  debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(body: ImageGridView()),
    );
  }
}

class ImageGridView extends StatelessWidget {
  List<File> _fileList = [];
  ImageGridView(){
    _fileList = [
        File('C:/flutter/img/1.jpg'),
        File('C:/flutter/img/3.jpg'),
        File('C:/flutter/img/4.jpg'),
        File('C:/flutter/img/5.jpg'),
        File('C:/flutter/img/6.jpg'),
        File('C:/flutter/img/7.jpg'),
        File('C:/flutter/img/8.jpg'),
        File('C:/flutter/img/9.jpg'),
        File('C:/flutter/img/10.jpg'),
        File('C:/flutter/img/11.jpg'),
        File('C:/flutter/img/12.jpg'),
        File('C:/flutter/img/13.jpg'),
        File('C:/flutter/img/14.jpg'),
        File('C:/flutter/img/15.jpg'),
        File('C:/flutter/img/16.jpg'),
      ];
    }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Wrap(
        children: _fileList.map((file) {
          return WindowsAsset(file);
        }).toList(),
      ),
    );
  }
}

class WindowsAsset extends StatefulWidget {
  final File _file;

  WindowsAsset(this._file);

  @override
  State<StatefulWidget> createState() => WindowsAssetState();
}

class WindowsAssetState extends State<WindowsAsset> {
  bool selected = false;

  @override
  Widget build(BuildContext context) {
    final width = MediaQuery.of(context).size.width / 2;
    final height = width * 1080 / 1920;
    return Container(
      width: width,
      height: height,
      child: Container(
        child: Container(
          constraints: BoxConstraints.expand(),
          decoration: !selected
              ? null
              : BoxDecoration(
                  border: Border.all(
                    color: Color.fromRGBO(153, 209, 255, 1),
                    width: 4
                  ),
                ),
          child: Container(
            child: GestureDetector(
              child: Image.file(
                widget._file,
                filterQuality: FilterQuality.medium,
                fit: BoxFit.fill,
                gaplessPlayback: true,
              ),
              onTap: () => setState(() {
                selected = !selected;
              }),
            ),
          ),
        ),
      ),
    );
  }
}

我该如何解决?谢谢!

最佳答案

这可能是因为 1. ImageCache 约束和 2. 将所有图像嵌套在 Wrap 中的混合。

ImageCache 具有可在内存中缓存的最大图像数以及最大总字节数。当达到该限制时,旧图像将被逐出,为新图像腾出空间。当尝试显示先前从缓存中逐出的图像时,将其再次加载到内存中需要一些时间,因此会出现白色闪烁。您可以根据 How do I change or replace the ImageCache in Flutter? 更改缓存的限制

默认图像缓存限制是 1000 个不同的图像,总共 100MiB,如果没有构建屏幕外小部件的最佳布局,这通常就足够了。
Wrap可能是您的问题的主要原因 - 我相信它会在内部构建其所有子项,以便弄清楚如何包装它们。在您的情况下,这将是所有图像。可能是因为Wrap ,您的所有图像都被视为在屏幕上,因此不会从缓存中逐出 - 这可以解释为什么即使您没有重建整个小部件树,GIF 中的某些图像也会闪烁 - 因为这些图像没有被缓存,因为缓存是已满,并且无法驱逐任何图像。

您可能想要替换 WrapGridView.builder ,它只会构建屏幕上的小部件。

如果图像太大而无法在缓存中容纳您一次显示的数量,您可能会遇到同样的问题。如果在 10x10 容器中显示 50MB 的图像,仍然需要 50MB 的内存缓存。

关于image - 重绘图像时出现白色闪烁 [ flutter ​​],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60125831/

相关文章:

c# - 多个图像处理程序调用导致 IE 在弹出窗口中挂起

image - Laravel将图像保存到公用文件夹?

flutter - flutter :为什么当textField失去焦点时输入内容消失了?

flutter - 什么情况下 textAlign 属性在 Flutter 中有效?

flutter - 使用纯 Dart 在本地打印机上打印文件并弹出打印机窗口?

flutter - 如何更改flutter桌面中的标题栏图标

Python PIL getdata() 方法不返回元组

windows - 跨进程发送图像的最有效方式

flutter - 如何将小部件放在 flutter 中的模态障碍上方?