google / flutter.widgets

https://pub.dev/packages/flutter_widgets
BSD 3-Clause "New" or "Revised" License
1.34k stars 460 forks source link

jumpTo does not jump to correct list element #144

Open rufat-badal opened 4 years ago

rufat-badal commented 4 years ago

Problem description

jumpTo method of ItemScrollController (from the scrollable_positioned_list package) does not jump to specified list position in the case of a long list of Text widgets of varying length. Maybe the mistake is on my side. In any case I would be super happy if some maintainer might take a look. Thx in advance!!

Steps to reproduce

Here is a minimal main.dart file that has the problem stated above:

import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'dart:math';

const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ?!.';
Random rnd = Random(42);
String getRandomString(int length) => String.fromCharCodes(Iterable.generate(
    length, (_) => chars.codeUnitAt(rnd.nextInt(chars.length))));
List<String> notes = [];

void main() {
  for (var i = 0; i < 202; i++) {
    notes.add(getRandomString(rnd.nextInt(101)));
  }
  runApp(MyApp());
} 

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StoryView(),
    );
  }
}

class StoryView extends StatefulWidget {
  @override
  _StoryViewState createState() => _StoryViewState();
}

class _StoryViewState extends State<StoryView> {
  final ItemScrollController _scrollController = ItemScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Does not jump to 101.",
        ),
        actions: <Widget>[
          IconButton(
            icon: Icon(
              Icons.arrow_upward,
            ),
            onPressed: () => _scrollController.jumpTo(index: 0),
          ),
          IconButton(
            icon: Icon(
              Icons.arrow_downward,
            ),
            onPressed: () => _scrollController.jumpTo(index: 101),
          ),
        ],
      ),
      body: _buildView(),
    );
  }

  Widget _buildNote(int index) {
    return Align(
      alignment: Alignment.center,
      child: FractionallySizedBox(
        widthFactor: 0.8,
        child: Text(
          index.toString().padLeft(3, "0") + ". " + notes[index],
        ),
      ),
    );
  }

  Widget _buildView() {
    return Container(
      child: ScrollablePositionedList.separated(
        itemCount: notes.length,
        itemBuilder: (context, index) => _buildNote(index),
        separatorBuilder: (BuildContext _context, int index) {
          return SizedBox(
            height: 30.0,
          );
        },
        itemScrollController: _scrollController,
      ),
    );
  }
}

Expected behavior

We are creating a list of 202 random strings which will be displayed in a ScrollablePositionedList. The are two action buttons in the top bar. The upward pointing arrow makes the list jump to element 0, while the downward pointing arrow makes the list jump to element 101.

Actual behavior

For certain initial scroll positions (e.g., in the vicinity of list element 47, but also others) the list does not jump to the start of element 101 but slightly past it. For some scroll positions the offset is even larger. Note that my list is generated at random so the ``bad'' starting positions might be different in your case.

Environment

Here is my pubspec.yaml file:

name: JumpToBug
description: A new Flutter project.

publish_to: 'none'

version: 1.0.0+1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.3
  scrollable_positioned_list: ^0.1.6

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

Additional details

Here is a short screen recording:

jumpTo_bug

lff5 commented 3 years ago

reproducible with 1.0.9. One interesting detail: second jumpTo() to same position shifts to correct position.

[✓] Flutter (Channel stable, 1.22.5, on Mac OS X 10.14.6 18G6032 darwin-x64, locale en-EE) [✓] Xcode - develop for iOS and macOS (Xcode 11.3) [✓] VS Code (version 1.52.1)

jamesderlin commented 3 years ago

Thanks for the reproduction case! However, I am not able to reproduce the problem. Possibly this has been fixed already?

Please reopen if this is still a problem.

Note that my list is generated at random so the ``bad'' starting positions might be different in your case.

FYI, since you initialized the random number generator with a fixed seed, the generated random values should be consistent (unless the Random implementation in the Dart SDK changes).

lff5 commented 3 years ago

@jamesderlin thanks for looking into it. This issue is not solved. I assume you are not on dev channel.

I can reproduce it most of the times when clicking up arrow (goto 000), then manually scroll down to around 050 and click the down arrow. it overshoots. I tried to do it programmatically but with no avail so far. Also seeded randomness has no effect here - I have identical generated elements as in the video above (validate yours - 000 must be LG?gm).

Some observations:

I encounter this problem on my project very often but I haven't had the time to reduce it down. @jamesderlin I could privately share my project where i managed to programmatically automate it (4 jumps in row all misaligned) - so that you could directly debug ScrollablePositionedList (still depends on screen size and orientation).

jamesderlin commented 3 years ago

Thanks. I can reproduce it now.

rufat-badal commented 3 years ago

Thanks @smartyboy for reproducing the bug! I could not find the time to check if it still reappears in a more recent version.

Just a comment on the ''strange'' looking example. As you did, I encountered this bug in my own private project. (Actually I am surprised that only few people encounter it. Maybe my lists are longer than most people ones.) As I did not want to share my rather long and convoluted code I reduced the problem to the bare minimum.

Hopefully the programmer of jumpTo might take a look. In the case of my project this bug forced me to change my design and not use the scrollable_positioned_list package.

valerybodak commented 3 years ago

The same for version 0.1.9

lff5 commented 3 years ago

Seems like related with #222

lff5 commented 3 years ago

Updated to 0.1.10 and haven't seen the issue since on my app (didn't test with the reproduction code sample though). Good job and thanks a ton! The issue should be closed now.

rufat-badal commented 3 years ago

I tried the sample code with version 0.1.10 and the bug still exists. Can someone else please also verify this?

jamesderlin commented 3 years ago

This should not be closed. This is not fixed and is not expected to be fixed yet. @smartyboy likely was encountering a separate problem.