Skip to content

PrimaryScrollController attached to multiple scroll views in TabBarView's keep-alive tabs #81152

@narumi147

Description

@narumi147

Recently, scroll views will auto generate a scrollbar on desktop. (?) In TabBarView, if we set every tab(with scrollable child like listview) keep-alive, then the auto generated scrollbar controller will attached to every tab. Then it will raise ScrollController attached to multiple scroll views. if we drag scrollbar after switching tab once.

Steps to Reproduce:

Run example code on desktop(windows/macOS):

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        bottom: TabBar(
          tabs: [Tab(text: 'TAB A'), Tab(text: 'TAB B')],
          controller: _tabController,
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          KeepAliveBuilder(builder: (ctx) => ChildPage(name: 'Tab A')),
          KeepAliveBuilder(builder: (ctx) => ChildPage(name: 'Tab B')),
        ],
      ),
    );
  }
}

class ChildPage extends StatelessWidget {
  final String name;

  const ChildPage({Key? key, required this.name}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: List.generate(
        20,
        (index) => ListTile(
          title: Text('$name: $index'),
        ),
      ),
    );
  }
}

class KeepAliveBuilder extends StatefulWidget {
  final WidgetBuilder builder;
  final bool wantKeepAlive;

  const KeepAliveBuilder(
      {Key? key, required this.builder, this.wantKeepAlive = true})
      : super(key: key);

  @override
  _KeepAliveBuilderState createState() => _KeepAliveBuilderState(wantKeepAlive);
}

class _KeepAliveBuilderState extends State<KeepAliveBuilder>
    with AutomaticKeepAliveClientMixin {
  bool _wantKeepAlive;

  _KeepAliveBuilderState(this._wantKeepAlive);

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.builder(context);
  }

  @override
  bool get wantKeepAlive => _wantKeepAlive;
}

Expected results:

Actual results:

Logs

error

======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
ScrollController attached to multiple scroll views.
'package:flutter/src/widgets/scroll_controller.dart':
Failed assertion: line 109 pos 12: '_positions.length == 1'


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

When the exception was thrown, this was the stack: 
#2      ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:109:12)
#3      RawScrollbarState.getScrollbarDirection (package:flutter/src/widgets/scrollbar.dart:1080:34)
#4      RawScrollbarState.handleThumbPressStart (package:flutter/src/widgets/scrollbar.dart:1103:29)
#5      _MaterialScrollbarState.handleThumbPressStart (package:flutter/src/material/scrollbar.dart:388:11)
#6      RawScrollbarState._gestures.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/scrollbar.dart:1239:74)
...
Handler: "onLongPressStart"
Recognizer: _ThumbPressGestureRecognizer#0c12c
  debugOwner: _MaterialScrollbarState#6eb61(tickers: tracking 2 tickers)
  state: possible
====================================================================================================

flutter doctor -v

[✓] Flutter (Channel master, 2.2.0-11.0.pre.274, on macOS 11.2.2 20D80 darwin-x64, locale en-CN)
    • Flutter version 2.2.0-11.0.pre.274 at /Users/narumi/Library/flutter-master
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision d1f73a1065 (33 hours ago), 2021-04-24 00:44:02 -0400
    • Engine revision eba9efd1c3
    • Dart version 2.14.0 (build 2.14.0-37.0.dev)
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/narumi/Library/Android/sdk
    • Platform android-30, build-tools 30.0.2
    • Java binary at: /Users/narumi/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    • CocoaPods version 1.10.1

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

[✓] Android Studio
    • Android Studio at /Users/narumi/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-1/202.7094744/Android Studio 4.2
      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
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] Android Studio (version 4.1)
    • Android Studio at /Users/narumi/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/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 1.8.0_242-release-1644-b3-6915495)

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

[!] Proxy Configuration
    • HTTP_PROXY is set
    ! NO_PROXY is not set

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 11.2.2 20D80 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 90.0.4430.85

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: error messageError messages from the Flutter frameworkc: crashStack traces logged to the consoled: api docsIssues with https://api.flutter.dev/d: stackoverflowGood question for Stack Overflowf: scrollingViewports, list views, slivers, etc.found in release: 2.2Found to occur in 2.2frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions