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

Scrollable.ensureVisible does not work with nested SingleChildScrollViews on both axes #65100

Closed
orischwartz opened this issue Sep 2, 2020 · 12 comments · Fixed by #65226 or #67773
Closed
Labels
f: scrolling Viewports, list views, slivers, etc. found in release: 1.22 Found to occur in 1.22 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on

Comments

@orischwartz
Copy link
Contributor

orischwartz commented Sep 2, 2020

Steps to Reproduce

  1. Run the sample app below. It creates a grid of cells using a Column of Rows and two SingleChildScrollViews--one for Axis.horizontal and the other for Axis.vertical.

image

Expected results:
Tapping any cell should center that cell in the viewport via ensureVisible.

         Scrollable.ensureVisible(context,
            alignment: .5,
            duration: Duration(
              milliseconds: 500,
            ));

Actual results:
Cells are not centered as expected. This works correctly when using just a single SingleChildScrollView but not with two.

ensureVisible does traverse all the Scrollables in the context:

ScrollableState scrollable = Scrollable.of(context);
while (scrollable != null) {
futures.add(scrollable.position.ensureVisible(
context.findRenderObject(),
alignment: alignment,
duration: duration,
curve: curve,
alignmentPolicy: alignmentPolicy,
));
context = scrollable.context;
scrollable = Scrollable.of(context);
}

But something about nesting the scrollviews will yield different values here:

RevealedOffset getOffsetToReveal(RenderObject target, double alignment, { Rect rect }) {

This behavior has been present since 2019 and is reproducible on the latest beta branch on both iOS and Android.

import 'package:flutter/material.dart';

void main() async {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Grid(),
      ),
    ),
  );
}

class Grid extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    List<Row> rows = List.generate(
      15,
      (y) => Row(
        children: List.generate(
          12,
          (x) => Cell(
            child: Text("$x,$y"),
          ),
        ),
      ),
    );

    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: Column(
          children: rows,
        ),
      ),
    );
  }
}

class Cell extends StatelessWidget {
  final Widget child;

  const Cell({
    this.child,
  });

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        Scrollable.ensureVisible(context,
            alignment: .5,
            duration: Duration(
              milliseconds: 500,
            ));
      },
      child: Container(
        width: 100,
        height: 100,
        color: Colors.grey.withOpacity(.2),
        margin: EdgeInsets.all(3),
        child: Center(
          child: child,
        ),
      ),
    );
  }
}
@pedromassangocode
Copy link

Hi @orischwartz
Can you please provide your flutter doctor -v?
Thank you

@pedromassangocode pedromassangocode added in triage Presently being triaged by the triage team waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds labels Sep 2, 2020
@orischwartz
Copy link
Contributor Author

orischwartz commented Sep 2, 2020

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[v] Flutter (Channel beta, 1.20.0-7.2.pre, on Microsoft Windows [Version 10.0.18362.1016], locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses
[v] Android Studio (version 4.0)
[v] VS Code (version 1.47.2)
[v] Connected device (1 available)

! Doctor found issues in 1 category.

But this is reproducible on all builds/platforms since at least August 2019 -- no special setup required.

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Sep 2, 2020
@xu-baolin
Copy link
Member

I am currently investigating this issue.

@pedromassangocode
Copy link

I was able to reproduce this on latest master channel. The scroll is not happening in both directions at the same time.

flutter doctor -v
[✓] Flutter (Channel master, 1.22.0-10.0.pre.65, on Mac OS X 10.15.6 19G2021, locale
    en)
    • Flutter version 1.22.0-10.0.pre.65 at
      /Users/pedromassango/dev/SDKs/flutter_master
    • Framework revision 2032a448ed (81 minutes ago), 2020-09-02 23:36:19 -0700
    • Engine revision 165abef0a2
    • Dart version 2.10.0 (build 2.10.0-77.0.dev)

 
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
    • Android SDK at /Users/pedromassango/Library/Android/sdk
    • Platform android-30, build-tools 30.0.1
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor
      --android-licenses

[✓] Xcode - develop for iOS and macOS (Xcode 11.7)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.7, Build version 11E801a
    • CocoaPods version 1.9.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)

[✓] IntelliJ IDEA Community Edition (version 2020.2.1)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 48.1.4
    • Dart plugin version 202.7206

[✓] VS Code (version 1.48.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.13.2

[✓] Connected device (4 available)
    • sdk gphone x86 arm (mobile) • emulator-5554 • android-x86    • Android 11 (API
      30) (emulator)
    • macOS (desktop)             • macos         • darwin-x64     • Mac OS X 10.15.6
      19G2021
    • Web Server (web)            • web-server    • web-javascript • Flutter Tools
    • Chrome (web)                • chrome        • web-javascript • Google Chrome
      85.0.4183.83

! Doctor found issues in 2 categories.

@pedromassangocode pedromassangocode added f: scrolling Viewports, list views, slivers, etc. found in release: 1.22 Found to occur in 1.22 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on and removed in triage Presently being triaged by the triage team labels Sep 3, 2020
@xu-baolin
Copy link
Member

xu-baolin commented Sep 3, 2020

@orischwartz
I found the cause of the problem.
The outer Scrollable is responsible for the horizontal adjust, When it calculates the adjustment displacement, it calculates all the cells as a whole, not the one clicked, so the whole is centered in the horizontal direction.

I modified the related algorithm(xu-baolin@49bc50c), and now it works as expected
20200903_165511
But I'm not sure the expectation is correct for this sample code.
@HansMuller @Piinks @Hixie Would you guys mind taking a look at the behavior?

@dnfield
Copy link
Contributor

dnfield commented Sep 29, 2020

Fix had to be reverted. Will try to come up with a new test case covering the breakage.

@dnfield
Copy link
Contributor

dnfield commented Sep 30, 2020

Quick update here: I'm starting to suspect the internal test this broke just needs to be updated. Trying to find the owners of that test to discuss further.

At a high level, the test is using ensureVisible and taking a screenshot. I think that it might not be waiting long enough now to take the screenshot, and that it might have been expecting the wrong element to be centered.

@dnfield
Copy link
Contributor

dnfield commented Sep 30, 2020

Ok! The basic problem here if you have a TabView or PageView that has Rows in its listview, and you try to scroll something on the righthand side of the screen in thef rist page/tab, it will actually now move you to the second tab. This is not desired behavior.

We might be able to somehow use the hasImplicitScrolling flag to work with this. I'll add a test case to clarify what needs to pass.

@xu-baolin
Copy link
Member

Ok! The basic problem here if you have a TabView or PageView that has Rows in its listview, and you try to scroll something on the righthand side of the screen in thef rist page/tab, it will actually now move you to the second tab. This is not desired behavior.

We might be able to somehow use the hasImplicitScrolling flag to work with this. I'll add a test case to clarify what needs to pass.

Thank you very much for your investigation and additional test cases. :)
I think we can't directly change its behavior, but through a parameter to control it so that developers can choose the scrolling behavior. I will fix it as soon as possible.

@dnfield
Copy link
Contributor

dnfield commented Oct 9, 2020

I believe I have a fix for this. Posting a PR.

@dnfield
Copy link
Contributor

dnfield commented Oct 9, 2020

My original instinct to try to use allowImplicitScrolling was wrong, but an easier solution was to just discard the targetRenderObject in _PagePosition's implementation of ScrollPosition.

@github-actions
Copy link

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 -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
f: scrolling Viewports, list views, slivers, etc. found in release: 1.22 Found to occur in 1.22 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on
Projects
None yet
4 participants