我用网络图像创建了一个列表视图,当我尝试滚动列表视图时,滚动并不顺畅,感觉就像在抽动一样。对于缓存,我使用了cached_network_image:any,该库本身运行良好,但listview滚动不流畅。
我知道我们可以使用Future小部件来实现此目的,但是不知道如何在将来返回缓存的图像。
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(
MaterialApp(
title: 'List view with network images',
home: ListViewController(),
)
);
}
class ListViewController extends StatelessWidget {
var imagesArray = [
"http://iastro.shangcarts.com/pub/media/notice/File-1550484786.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550218043.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550217808.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550111913.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550108862.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550024618.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550022739.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549935759.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549935073.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549850545.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549849978.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549008412.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548985261.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548821873.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548731040.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548641672.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548410089.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547774905.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547701178.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547625318.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547624883.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547619153.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547606341.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547606200.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547603338.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547602464.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547454842.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547192524.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547191374.jpg"
];
Widget _imageCell(String imageUrl) {
return ListTile(
leading: CachedNetworkImage(imageUrl: imageUrl, placeholder: CircularProgressIndicator(), errorWidget: Icon(Icons.error),),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Material(
child: ListView.separated(
itemBuilder: (BuildContext context, int index) {
return _imageCell(imagesArray[index]);
},
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
itemCount: imagesArray.length),
);
}
}
编辑:将构建配置更改为“发布”后,仍然保持抽动。
答案 0 :(得分:5)
两件事
FadeInImage.memoryNetwork
代替cached_network_image
,和/或ListView(children: List<Widget> )
代替ListView.separated(itemBuilder: )
FadeInImage.memoryNetwork
参考https://flutter.dev/docs/cookbook/images/fading-in-images
在运行示例代码时,我不禁注意到cached_network_image
进行了一些图像缩放/采样操作,从而影响了主UI线程,此程序包可能正在主线程上执行大量计算任务。使用官方的烹饪书对我(Android模拟器)产生更好的结果,完整的示例代码(您可能希望将kTransparentImage
更改为其他加载图标)
import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';
void main() {
runApp(MaterialApp(
title: 'List view with network images',
home: ListViewController(),
));
}
class ListViewController extends StatelessWidget {
var imagesArray = [
"http://iastro.shangcarts.com/pub/media/notice/File-1550484786.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550218043.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550217808.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550111913.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550108862.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550024618.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550022739.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549935759.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549935073.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549850545.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549849978.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549008412.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548985261.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548821873.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548731040.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548641672.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548410089.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547774905.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547701178.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547625318.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547624883.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547619153.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547606341.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547606200.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547603338.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547602464.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547454842.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547192524.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547191374.jpg"
];
Widget _imageCell(String imageUrl) {
return ListTile(
leading: FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image: imageUrl,
));
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Material(
child:
ListView.separated(
itemBuilder: (BuildContext context, int index) {
return _imageCell(imagesArray[index]);
},
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
itemCount: imagesArray.length),
);
}
}
ListView(children: List<Widget> )
参考https://docs.flutter.io/flutter/widgets/ListView-class.html
第二,如果您事先知道将要有这个有限的不太长的列表,则可能要使用ListView(children: List<Widget> )
而不是ListView.separated(itemBuilder: )
,因为itemBuilder
将调用/调用函数的频率更高,现在仅将图像缓存(通过FadeInImage.memoryNetwork
或cached_network_image
)用于全部内容,不用于缩略图,@ user1462442提及源图像大小,我同意这一评估。我们可以做的就是将调用次数减少到尽可能少的数目。
例如代码:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(MaterialApp(
title: 'List view with network images',
home: ListViewController(),
));
}
class ListViewController extends StatelessWidget {
var imagesArray = [
"http://iastro.shangcarts.com/pub/media/notice/File-1550484786.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550218043.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550217808.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550111913.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550108862.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550024618.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1550022739.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549935759.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549935073.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549850545.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549849978.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1549008412.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548985261.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548821873.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548731040.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548641672.jpeg",
"http://iastro.shangcarts.com/pub/media/notice/File-1548410089.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547774905.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547701178.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547625318.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547624883.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547619153.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547606341.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547606200.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547603338.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547602464.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547454842.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547192524.jpg",
"http://iastro.shangcarts.com/pub/media/notice/File-1547191374.jpg"
];
Widget _imageCell(String imageUrl) {
return ListTile(
leading: CachedNetworkImage(
imageUrl: imageUrl,
placeholder: CircularProgressIndicator(),
errorWidget: Icon(Icons.error),
),
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Material(
child: ListView(
children: imagesArray.map((imageUrl) => _imageCell(imageUrl)).toList(),
),
);
}
}
如前所述,您也可以同时应用这两个建议。
答案 1 :(得分:0)
除了缩小源图像大小外,我认为目前没有很好的解决方案。我查看了您的图片列表,其中一些图片非常大。
https://github.com/renefloor/flutter_cached_network_image/issues/90
https://github.com/pejalo/flutter_image_performance
https://github.com/flutter/flutter/issues/25469
https://github.com/flutter/flutter/issues/27625#issuecomment-461677587
https://github.com/flutter/flutter/issues/2848
https://github.com/flutter/flutter/issues/26194
颤振降级相当慢。 Flutter团队必须对其进行优化以提高性能。
另一件事,您的代码无法在稳定的抖动上运行
Flutter 1.0.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 5391447fae (3 months ago) • 2018-11-29 19:41:26 -0800
Engine • revision 7375a0f414
Tools • Dart 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)
Compiler message:
lib/main.dart:56:64: Error: The argument type '#lib1::CircularProgressIndicator'
can't be assigned to the parameter type '(#lib2::BuildContext, dart.core::String)
→ #lib2::Widget'.
Try changing the type of the parameter, or casting the argument to
'(#lib2::BuildContext, dart.core::String) → #lib2::Widget'.
leading: CachedNetworkImage(imageUrl: imageUrl, placeholder:
CircularProgressIndicator(), errorWidget: Icon(Icons.error),),
^
lib/main.dart:56:106: Error: The argument type '#lib1::Icon' can't be assigned to
the parameter type '(#lib2::BuildContext, dart.core::String, dart.core::Exception)
→ #lib2::Widget'.
Try changing the type of the parameter, or casting the argument to
'(#lib2::BuildContext, dart.core::String, dart.core::Exception) → #lib2::Widget'.
leading: CachedNetworkImage(imageUrl: imageUrl, placeholder:
CircularProgressIndicator(), errorWidget: Icon(Icons.error),),
^
Compiler failed on /Users/blah/stackoverflow/issue_54786567/lib/main.dart
Error launching application on iPhone XR.
flutter run
Launching lib/main.dart on iPhone XR in debug mode...
Starting Xcode build...
├─Assembling Flutter resources... 3.9s
└─Compiling, linking and signing... 3.4s
Xcode build done. 9.1s
5.8s
Syncing files to device iPhone XR...
flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performLayout():
flutter: BoxConstraints forces an infinite height.
flutter: These invalid constraints were provided to RenderSemanticsAnnotations's layout() function by the
flutter: following function, which probably computed the invalid constraints in question:
flutter: RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:258:13)
flutter: The offending constraints were:
flutter: BoxConstraints(w=382.0, h=Infinity)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:504:9)
flutter: #1 BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:547:21)
flutter: #2 BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:551:6)
flutter: #3 RenderObject.layout (package:flutter/src/rendering/object.dart:1549:24)
flutter: #4 RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:258:13)
flutter: #5 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #6 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
flutter: #7 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #8 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
flutter: #9 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #10 _RenderListTile._layoutBox (package:flutter/src/material/list_tile.dart:892:9)
flutter: #11 _RenderListTile.performLayout (package:flutter/src/material/list_tile.dart:913:30)
flutter: #12 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #13 RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:199:11)
flutter: #14 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #15 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
flutter: #16 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #17 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
flutter: #18 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #19 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
flutter: #20 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #21 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
flutter: #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #23 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
flutter: #24 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #25 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:164:27)
flutter: #26 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #27 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:182:11)
flutter: #28 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
flutter: #29 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:405:13)
flutter: #30 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1316:12)
flutter: #31 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1234:20)
flutter: #32 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1509:7)
flutter: #33 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:768:18)
flutter: #34 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:281:19)
flutter: #35 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:677:13)
flutter: #36 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
flutter: #37 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
flutter: #38 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
flutter: #39 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
flutter: #40 _invoke (dart:ui/hooks.dart:154:13)
flutter: #41 _drawFrame (dart:ui/hooks.dart:143:3)
flutter:
flutter: The following RenderObject was being processed when the exception was fired:
flutter: RenderConstrainedBox#57507 relayoutBoundary=up12 NEEDS-LAYOUT NEEDS-PAINT
flutter: creator: ConstrainedBox ← Container ← FadeTransition ← Stack ← StreamBuilder<FileInfo>-[#fb1e3] ←
flutter: CachedNetworkImage ← IconTheme ← Builder ← _ListTile ← MediaQuery ← Padding ← SafeArea ← ⋯
flutter: parentData: <none> (can use size)
flutter: constraints: BoxConstraints(0.0<=w<=382.0, 0.0<=h<=Infinity)
flutter: size: MISSING
flutter: additionalConstraints: BoxConstraints(biggest)
flutter: This RenderObject had the following descendants (showing up to depth 5):
flutter: RenderSemanticsAnnotations#494da NEEDS-LAYOUT NEEDS-PAINT
flutter: RenderImage#98201 NEEDS-LAYOUT NEEDS-PAINT
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#57507 relayoutBoundary=up12 NEEDS-PAINT
flutter: Another exception was thrown: BoxConstraints forces an infinite height.
flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#ac73c relayoutBoundary=up12 NEEDS-PAINT
flutter: Another exception was thrown: BoxConstraints forces an infinite height.
flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#95164 relayoutBoundary=up12 NEEDS-PAINT
flutter: Another exception was thrown: BoxConstraints forces an infinite height.
flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#9efb3 relayoutBoundary=up12 NEEDS-PAINT
flutter: Another exception was thrown: BoxConstraints forces an infinite height.
flutter: Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#16fcc relayoutBoundary=up12 NEEDS-PAINT
flutter: Another exception was thrown: BoxConstraints forces an infinite height.
我必须做一些修改。
答案 2 :(得分:0)
尝试将其添加到您的列表视图:
df_final = pd.DataFrame({('Year', 'XYZ'): {0: 2001, 1: 2001, 2: 2001, 3: 2001, 4: 2001, 5: 2001}, ('Year', 'ABC'): {0: 2001, 1: 2001, 2: 2001, 3: 2001, 4: 2001, 5: 2001}, ('Quantity', 'XYZ'): {0: 16, 1: 20, 2: 44, 3: 200, 4: 1000, 5: 16}, ('Quantity', 'ABC'): {0: 16, 1: 20, 2: 44, 3: 200, 4: 1000, 5: 16}, ('Car', 'XYZ'): {0: 'Wagonar', 1: 'Zen', 2: np.nan, 3: 'Baleno', 4: 'Swift', 5: 'Wagonar'}, ('Car', 'ABC'): {0: 'Wagonar', 1: np.nan, 2: 'Alto', 3: 'Baleno', 4: 'Swift', 5: np.nan}, ('Colour', 'XYZ'): {0: 'White', 1: 'White', 2: np.nan, 3: 'Silver', 4: 'Red', 5: 'Black'}, ('Colour', 'ABC'): {0: 'White', 1: np.nan, 2: 'Blue', 3: 'Silver', 4: 'Red', 5: np.nan}})
如果您正在仿真器上进行测试,建议您构建发行版APK,将APK安装在Android手机上,然后检查它是否仍然生涩。模拟器占用了资源,因此可能是原因。
最后,您可以尝试减少图像数量,图像类型或尺寸,以查看其是否仍然滞后。
Else在github上报告了此问题,以便颤振团队知道。
答案 3 :(得分:0)
我也研究了一个月,经过大量研究,我发现了一行代码,可以使列表视图或任何列表平滑滚动
只需使用 physics 属性作为 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
并感受不同
此外,如果您希望将其用于 Column,您可以使用 Singlechildscrollview,并且您可以使用物理属性。