Repository navigation
ListView scrolling exception when item is a dynamic height web image #143817
Description
Steps to reproduce
The listview loads the web image, and when I scroll anywhere below (index10 in the video) and then scroll up, it scrolls right back to the beginning.Found it on my ios 16.5 and 17.3 devices at first, then realized it's the same on the dartpad.
If I use a fixed height it's fine, but I have no way of knowing the image height. If I use cacheExtent: maxFinite it's also fine, but the number of images is potentially so large that I can't use it and it will cause too much memory causing the app to crash!
I think this is a very serious problem, it's too much of an impact on the user experience
Expected results
I've used cacheExtent:1000, which shouldn't scroll back to the beginning, but should smoothly scroll to where it should be
Actual results
Scroll to the beginning
Code sample
Code sample
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(const CupertinoApp(home: TestListView2()));
final testUrls = List.generate(
24,
(index) =>
"https://s2.baozicdn.com/scomic/fanpaidashixiongshimeimenquanshibingjiao-pikapi/0/1-i8qs/${index + 1}.jpg");
class TestListView2 extends StatelessWidget {
const TestListView2({super.key});
@override
Widget build(BuildContext context) {
return ListView.builder(
cacheExtent: 1000,
itemCount: testUrls.length,
itemBuilder: (context, index) {
return Container(
color: Colors.white,
child: Image.network(
testUrls[index],
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return Column(
children: [
child,
Text("index $index"),
],
);
} else {
return SizedBox(child: Text("loading...$index"));
}
},
),
);
},
);
}
}Screenshots or Video
Screenshots / Video demonstration
[Upload media here]
f2-output.mp4
Logs
Logs
[Paste your logs here]Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.19.0, on macOS 13.6.1 22G313 darwin-x64, locale zh-Hans-CN)
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
✗ cmdline-tools component is missing
Run `path/to/sdkmanager --install "cmdline-tools;latest"`
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] VS Code (version 1.86.2)
[!] Proxy Configuration
! NO_PROXY is not set
[✓] Connected device (4 available)
[✓] Network resources
Activity
dam-ease commentedon Feb 21, 2024
Helllo @fyxtc.
Thanks for filing this!
I can reproduce this on the latest
masterandstablechannels.This occurs when a specific
cacheExtentis set, settingcacheExtent: double.maxFiniteworks fine.stable, master flutter doctor -v
fyxtc commentedon Feb 21, 2024
@dam-ease
Thanks for your reply.
I commented out
cacheExtentand still the same thing happens, it should have nothing to do with cacheExtent. As I said above, settingcacheExtent: double.maxFinitesolves the problem, but directly causes a memory issue that crashes the app.And I don't think
cacheExtent: double.maxFinitemakes sense forListView.builder, theListViewis supposed to specify the rendering area for performance purposes, so if you use that value, it's the same performance as using theListView()/SingleChildScrollView().Piinks commentedon Feb 27, 2024
I would recommend loading and caching the images only once. Here, it looks like the image is being requested every time the child is being built. So when the child is in view, it requests the image, and then when it scrolls out of view it is disposed. Then when it scrolls back, the image is requested again. And so on.
Have you tried creating the
Image.networks outside of ListView.builder? So they are only created/requested once?fyxtc commentedon Feb 28, 2024
@Piinks Thanks for the reply, I understand the reason, I personally think it's a bug, first of all I've used
cacheExtent:1000, shouldn't the ListView cache 1000 pixels above the screen, why does scrolling back less than 100 pixels release all the images cached above it, which leads to a sudden decrease in the computed offset value, which directly causes the Scrolling back to the beginning and then loading from the beginning. It's so weird!I have used
precacheandCachedNetworkImageboth with the same problem, I really don't know what I can do, please help me!fyxtc commentedon Feb 28, 2024
@Piinks Would it be possible to provide an option for cacheExtentUp so that I can set infinity
Piinks commentedon Feb 28, 2024
I found #99158, which looks like a duplicate of this issue, so I am going to close this to consolidate there.
@fyxtc there are some discussions on different approaches to achieving your desired result there. Thank you for reporting, and please continue to follow at the linked issue. :)
github-actions commentedon Mar 14, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.