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

extendBodyBehindAppBar breaks ScrollController attachment #116120

Open
eEQK opened this issue Nov 28, 2022 · 3 comments
Open

extendBodyBehindAppBar breaks ScrollController attachment #116120

eEQK opened this issue Nov 28, 2022 · 3 comments
Labels
d: stackoverflow Good question for Stack Overflow f: material design flutter/packages/flutter/material repository. f: scrolling Viewports, list views, slivers, etc. found in release: 3.3 Found to occur in 3.3 found in release: 3.6 Found to occur in 3.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P3 Issues that are less important to the Flutter project team-design Owned by Design Languages team triaged-design Triaged by Design Languages team

Comments

@eEQK
Copy link
Contributor

eEQK commented Nov 28, 2022

I wanted to animate app bar depending on scroll position (with an image behind it, that's the whole point of animation):

That's how it looks like currently (with the snippet below, but after rebuilding the widget tree with setState):
output

After adding extendBodyBehindAppBar: true to the code, on initial load (before hot reload) the screen looks like this (screenshot from my example below):
image

Relevant snippet:

class _TestScreenState extends State<TestScreen> {
  final controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,           // remove this line to make it work
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(56),
        child: AnimatedBuilder(
          animation: controller,
          builder: (_, __) => AppBar(
            title: Text(controller.offset.toString()),
          ),
        ),
      ),
      body: ListView.builder(
        controller: controller,
        itemBuilder: (context, index) => SizedBox(
          height: 32,
          child: Text(index.toString()),
        ),
      ),
    );
  }
}

Stacktrace:

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building AnimatedBuilder(animation: ScrollController#2b8e3(no clients), dirty, state: _AnimatedState#548ce):
ScrollController not attached to any scroll views.
'package:flutter/src/widgets/scroll_controller.dart':
package:flutter/…/widgets/scroll_controller.dart:1
Failed assertion: line 107 pos 12: '_positions.isNotEmpty'

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was
AnimatedBuilder
package:playground/main.dart:30
When the exception was thrown, this was the stack
#2      ScrollController.position
package:flutter/…/widgets/scroll_controller.dart:107
#3      ScrollController.offset
package:flutter/…/widgets/scroll_controller.dart:115
#4      _TestScreenState.build.<anonymous closure>
package:playground/main.dart:33

Basically adding extendBodyBehindAppBar: true somehow causes the ScrollController to not get attached.

Reproducible example:
https://gist.github.com/eEQK/82c113b4c5471dd33961f8c07b750015
Reproducible example in dartpad:
https://dartpad.dev/?id=82c113b4c5471dd33961f8c07b750015

In order to reproduce, copy the code from the gist and run it in dartpad.dev or run it as an application

I can consistently reproduce it on:

  • dartpad.dev with both latest stable and master channel
  • Android 12 emulator
  • iOS 15.5 emulator
$ flutter --version
Flutter 3.3.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b8f7f1f986 (6 days ago) • 2022-11-23 06:43:51 +0900
Engine • revision 8f2221fbef
Tools • Dart 2.18.5 • DevTools 2.15.0
@danagbemava-nc danagbemava-nc added the in triage Presently being triaged by the triage team label Nov 29, 2022
@danagbemava-nc
Copy link
Member

Reproducible using the code sample in the gist shared above. Pasted below for convenience.

sample
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) => const MaterialApp(
        home: TestScreen(),
      );
}

class TestScreen extends StatefulWidget {
  const TestScreen({super.key});

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  final controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(56),
        child: AnimatedBuilder(
          animation: controller,
          builder: (_, __) => AppBar(
            title: Text(controller.offset.toString()),
          ),
        ),
      ),
      body: ListView.builder(
        controller: controller,
        itemBuilder: (context, index) => SizedBox(
          height: 32,
          child: Text(index.toString()),
        ),
      ),
    );
  }
}
logs
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building AnimatedBuilder(animation: ScrollController#805fa(no
flutter: clients), dirty, state: _AnimatedState#bcdce):
flutter: ScrollController not attached to any scroll views.
flutter: 'package:flutter/src/widgets/scroll_controller.dart':
flutter: Failed assertion: line 107 pos 12: '_positions.isNotEmpty'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter:   https://github.com/flutter/flutter/issues/new?template=2_bug.md
flutter:
flutter: The relevant error-causing widget was:
flutter:   AnimatedBuilder AnimatedBuilder:file:///Users/nexus/projects/nevercode/newday/lib/main.dart:30:16
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #2      ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:107:12)
flutter: #3      ScrollController.offset (package:flutter/src/widgets/scroll_controller.dart:115:24)
flutter: #4      _TestScreenState.build.<anonymous closure> (package:newday/main.dart:33:36)
flutter: #5      AnimatedBuilder.build (package:flutter/src/widgets/transitions.dart:1086:19)
flutter: #6      _AnimatedState.build (package:flutter/src/widgets/transitions.dart:133:48)
flutter: #7      StatefulElement.build (package:flutter/src/widgets/framework.dart:5080:27)
flutter: #8      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4968:15)
flutter: #9      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
flutter: #10     Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
flutter: #11     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4950:5)
flutter: #12     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5124:11)
flutter: #13     ComponentElement.mount (package:flutter/src/widgets/framework.dart:4944:5)
flutter: ...     Normal element mounting (28 frames)
flutter: #41     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3953:16)
flutter: #42     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6512:36)
flutter: #43     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6524:32)
flutter: ...     Normal element mounting (136 frames)
flutter: #179    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3953:16)
flutter: #180    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6512:36)
flutter: #181    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6524:32)
flutter: ...     Normal element mounting (172 frames)
flutter: #353    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3953:16)
flutter: #354    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6512:36)
flutter: #355    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6524:32)
flutter: ...     Normal element mounting (467 frames)
flutter: #822    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3953:16)
flutter: #823    Element.updateChild (package:flutter/src/widgets/framework.dart:3682:18)
flutter: #824    RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1176:16)
flutter: #825    RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1145:5)
flutter: #826    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1092:18)
flutter: #827    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2682:19)
flutter: #828    RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1091:13)
flutter: #829    WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:926:7)
flutter: #830    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:906:7)
flutter: #834    _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)
flutter: (elided 5 frames from class _AssertionError, class _Timer, and dart:async-patch)
flutter:
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter doctor -v
[✓] Flutter (Channel stable, 3.3.9, on macOS 13.0.1 22A400 darwin-arm, locale en-GB)
    • Flutter version 3.3.9 on channel stable at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision b8f7f1f986 (6 days ago), 2022-11-23 06:43:51 +0900
    • Engine revision 8f2221fbef
    • Dart version 2.18.5
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

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

[!] Android Studio
    • Android Studio at /Applications/Android Studio Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[!] Android Studio
    • Android Studio at /Applications/Android Studio Preview 2.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9014738/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

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

[✓] Connected device (3 available)
    • iPhone 14 Pro (mobile) • 4F72110C-F38B-4CF9-93C4-4D6042148D28 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64   • macOS 13.0.1 22A400 darwin-arm
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 107.0.5304.110

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 2 categories.
[!] Flutter (Channel master, 3.6.0-10.0.pre.12, on macOS 13.0.1 22A400 darwin-arm64, locale en-GB)
    • Flutter version 3.6.0-10.0.pre.12 on channel master at /Users/nexus/dev/sdks/flutters
    ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 853b3080e0 (3 hours ago), 2022-11-29 00:24:25 -0500
    • Engine revision ee8023432a
    • Dart version 2.19.0 (build 2.19.0-430.0.dev)
    • DevTools version 2.19.0
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

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

[!] Android Studio
    • Android Studio at /Applications/Android Studio Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[!] Android Studio
    • Android Studio at /Applications/Android Studio Preview 2.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9014738/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

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

[✓] Connected device (3 available)
    • iPhone 14 Pro (mobile) • 4F72110C-F38B-4CF9-93C4-4D6042148D28 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64   • macOS 13.0.1 22A400 darwin-arm64
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 107.0.5304.110

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 3 categories.

@danagbemava-nc danagbemava-nc added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. f: scrolling Viewports, list views, slivers, etc. has reproducible steps The issue has been confirmed reproducible and is ready to work on found in release: 3.3 Found to occur in 3.3 found in release: 3.6 Found to occur in 3.6 and removed in triage Presently being triaged by the triage team labels Nov 29, 2022
@darrenaustin darrenaustin removed the f: material design flutter/packages/flutter/material repository. label Dec 1, 2022
@goderbauer
Copy link
Member

@Piinks

@goderbauer goderbauer added d: stackoverflow Good question for Stack Overflow P3 Issues that are less important to the Flutter project labels Dec 6, 2022
@Piinks
Copy link
Contributor

Piinks commented Dec 7, 2022

It looks like the AppBar in the sample code is expecting the position to always be attached, this is not necessarily true.

The scroll controller may not have the position attached by the time the AppBar tries to access it. When extendBodyBehindAppBar is true, this is what is happening. The AppBar is built before the position has been created. When it is false, the position is created before the AppBar is built. Why that is I am not sure, but we should find out.

In general, if you are going to access the position on a scroll controller, it is good practice to check if ScrollController.hasClients first.

_BodyBuilder in Scaffold is likely where to look. It adds a LayoutBuilder if extendBodyBehindAppBar is true, and is likely where this change in behavior is coming from.

@Piinks Piinks added the f: material design flutter/packages/flutter/material repository. label Dec 7, 2022
@flutter-triage-bot flutter-triage-bot bot added multiteam-retriage-candidate team-design Owned by Design Languages team triaged-design Triaged by Design Languages team labels Jul 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
d: stackoverflow Good question for Stack Overflow f: material design flutter/packages/flutter/material repository. f: scrolling Viewports, list views, slivers, etc. found in release: 3.3 Found to occur in 3.3 found in release: 3.6 Found to occur in 3.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P3 Issues that are less important to the Flutter project team-design Owned by Design Languages team triaged-design Triaged by Design Languages team
Projects
None yet
Development

No branches or pull requests

6 participants