Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug report] Wrong observe results with small list and fast scrolling #113

Closed
nikita488 opened this issue Jan 27, 2025 · 5 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@nikita488
Copy link

Version

1.25.0

Platforms

Android

Device Model

Poco F6

flutter info

• Flutter version 3.24.3 on channel stable at D:\Dev\FlutterSDK\3.22.3
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2663184aa7 (5 months ago), 2024-09-11 16:27:48 -0500
    • Engine revision 36335019a8
    • Dart version 3.5.3
    • DevTools version 2.37.3

How to reproduce?

Sometimes there are wrong observe results, when i have a list with small amount of items (let's say 50 items) and when currently i near end of the list, and trying to scroll REALLY fast so that it reaches end almost immediatly, I expect last item to have index 49, but in reality it is 41 because of how quick it reached the end of the list.

I managed to fix this by wrapping this line

in WidgetsBinding.instance.addPostFrameCallback, so it observes results after frame end (exactly as you did it for Web).

So I'm proposing to wrap this line in WidgetsBinding.instance.addPostFrameCallback like you do on Web OR adding bool var "immediate" to ObserverWidget constructor that defaults to true to simulate old behaviour, and wrap it with addPostFrameCallback when it is false.

Logs

I/flutter (31017): First visible: 0
I/flutter (31017): Last visible: 41

Example code (optional)

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

void main() {
  runApp(const TestApp());
}

class TestApp extends StatelessWidget {
  const TestApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const MainApp(),
      scrollBehavior: kIsWeb ? _WebScrollBehavior() : null,
    );
  }
}

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListViewObserver(
          triggerOnObserveType: ObserverTriggerOnObserveType.directly,
          onObserve: (result) {
            print('First visible: ${result.firstChild?.index}');
            print(
                'Last visible: ${result.displayingChildModelList.lastOrNull?.index}');
          },
          child: ListView.builder(
            itemCount: 50,
            itemBuilder: (context, index) => Text('$index'),
          ),
        ),
      ),
    );
  }
}

class _WebScrollBehavior extends MaterialScrollBehavior {
  @override
  Set<PointerDeviceKind> get dragDevices =>
      {PointerDeviceKind.touch, PointerDeviceKind.mouse};
}

Contact

No response

@LinXunFeng LinXunFeng added the bug Something isn't working label Feb 2, 2025
@LinXunFeng
Copy link
Member

Fixed, please upgrade to version 1.25.1.

@nikita488
Copy link
Author

Actually in my real app, i use SuperSliverList, and 1.25.1 version fixed some of the observation problems, but sometimes it still observes it too early. I managed to fix all problems by replacing WidgetsBinding.instance.endOfFrame.then to WidgetsBinding.instance.addPostFrameCallback in your 1.25.1 version, it seems endOfFrame is still too early

@LinXunFeng
Copy link
Member

I replaced ListView with SuperListView and didn't reproduce the issue you said, can you provide code to reproduce the issue?

In addition, using WidgetsBinding.instance.addPostFrameCallback directly will result in other bugs, as shown in the following screen.

2025-02-03.22.15.33.mov

@LinXunFeng LinXunFeng reopened this Feb 3, 2025
@nikita488
Copy link
Author

Honestly, i wouldn't be able to provide code, cause it's app for a company, but I think a managed to fix this issue. I used in a few places manual observe (ListViewOnceObserveNotification(isForce: true).dispatch()), but I usually did this in addPostFrameCallback to be sure it will observe it after this frame, but now that you do observation in endOfFrame callback, it were called before automatic observation. So i changed my manual observes to be in endOfFrame too, and it seems it works fine now

@LinXunFeng
Copy link
Member

Okay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants