MG *_*ine 4 android dart flutter
好的,所以我想从 LinearView 获取项目并获得它们的可见性,这样我就可以释放隐藏项目的内存。
有可能这样做吗?你还有其他建议吗?
所以基本上,我想显示从 URL 动态下载的图像流,我希望它们在 ListView 中,这样人们就可以滚动它们,但是如果我们只是使用像这样的普通构建器加载 ListView,
ListView lvb = new ListView.builder(
cacheExtent: 1.0,
itemBuilder: (BuildContext context, int index) {
return new ImageView(MyApp.imageLinks.values.elementAt(index));
},
);
Run Code Online (Sandbox Code Playgroud)
它会一次下载所有项目,设备会耗尽内存。所以我想我只是释放图像占用的内存,然后允许用户加载更多图像而不必担心内存。
此外,我希望一次只加载 5 张图像,因此将显示 1 张,上方 2 张和下方 2 张,以便更快、更流畅地滚动。
我的问题:
编辑:承诺的 ImageView 类
class ImageView extends StatelessWidget {
String url;
ImageView([String url]) {
if (url != null) {
this.url = url;
}
print("New image");
}
@override
Widget build(BuildContext context) {
FractionallySizedBox fsb;
if (url != null) {
Image el = Image.network(
url,
scale: 0.1,
);
fsb = new FractionallySizedBox(
widthFactor: 1.0,
child: el,
);
print("New image created");
return fsb;
}
}
Run Code Online (Sandbox Code Playgroud)
一旦 ListView 开始列出项目,它就会开始向控制台发送垃圾邮件“已创建新图像”。
我将用不回答来回答这个问题。理论上可以确定是否使用 Slivers 和 CustomScrollView 或可能使用自定义 RenderObjects 来绘制项目,但我认为这不是您真正想要的。
除非您对图像做一些奇怪的事情EDIT: SEE END,否则使用 ListView.builder 旨在防止您描述的确切场景。
从ListView.builder 文档的第一行(重点是我的):
创建按需创建的可滚动的线性小部件数组。
使用 ListView.builder 而不是 new ListView([items]) 的想法是它应该自动处理你正在谈论的内容 - 只创建当前可见的元素。
如果您已经实现了这一点并且您实际上在真实设备上耗尽了内存,那么这将是一个很好的案例,可以向 Flutter 人员 =D 提出错误。
此外,设置cacheExtent为 1.0 实际上会降低性能。从cacheExtent 文档:
视口在可见区域之前和之后都有一个区域,用于缓存用户滚动时即将变为可见的项目。
落入该缓存区域的项目即使在屏幕上(尚)不可见,也会进行布局。cacheExtent 描述了缓存区域在视口的前缘之前和后缘之后延伸了多少像素。
通过将其设置为 1.0,您可以在图片离开视口时立即将其释放。并且下一个图像在它们几乎可见之前不会加载。因此,下次您滚动(向后或向前)时,(下一个或最后一个)图像必须在进入视图时加载。
如果您将其设置得更高(或将其保留为当前的默认值 250.0),您可以将其设置为让下一张图片提前加载,完全按照您的需要。
编辑:
所以这里还有一个额外的因素在起作用。感谢您发布您的 ImageView 代码。
问题是您使用的是带有 widthFactor 但没有 HeightFactor 的 FractionallySizedBox。您将宽度设置为 1.0,但没有高度(无论如何都行不通),因此它占用的空间为零,因此一直试图永远加载图像。
最好的办法是使用 SizedBox、ConstrainedBox 或 AspectRatio 为图像指定高度,然后使用Image.network的选项contain或cover其中fit之一。
这是一个有趣的例子 - 无限加载狗 =)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: Text("Title"),
),
body: ListView.builder(
cacheExtent: 1000.0,
itemBuilder: (BuildContext context, int index) {
return new ImageView(
num: index,
url: "https://loremflickr.com/640/480/dog?random=$index",
);
},
),
),
);
}
}
class ImageView extends StatelessWidget {
final int num;
final String url;
ImageView({@required this.num, @required this.url});
@override
Widget build(BuildContext context) {
print("Building image number $num");
return new AspectRatio(
aspectRatio: 3.0 / 2.0,
child: Image.network(
url,
fit: BoxFit.cover,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3644 次 |
| 最近记录: |