Matthew Trent
Matthew Trent

Reputation: 3274

Can't add ScrollBar to ScrollablePositionedList (it doesn't have a ScrollController)

I'm using the scrollable_positioned_list package, and have it rendering a large dynamic list. It works very well. However, I need my list to have a scrollbar (something like this). So far, this is impossible.

Does anyone know how to do it?

My code looks as follows:

Scrollbar(
          child: ScrollablePositionedList.builder(
            physics: const ClampingScrollPhysics(
              parent: AlwaysScrollableScrollPhysics(),
            ),
            itemCount: posts.length + 1,
            itemBuilder: (context, index) {
              if (index == 0) {
                return Container(
                  height: 200,
                  color: Colors.green,
                  child: const Center(
                    child: Text('post content'),
                  ),
                );
              } else if (posts[index - 1].isRoot) {
                return Container(
                  padding: const EdgeInsets.symmetric(vertical: 15),
                  margin: const EdgeInsets.symmetric(vertical: 5),
                  color: Colors.redAccent,
                  child: Text('ROOT COMMENT, index: ${index - 1}'),
                );
              } else {
                return Container(
                  padding: const EdgeInsets.symmetric(vertical: 15),
                  margin: const EdgeInsets.symmetric(vertical: 5),
                  color: Colors.lightBlueAccent,
                  child: Text('Threaded comment, index: ${index - 1}'),
                );
              }
            },
            itemScrollController: itemScrollController,
            itemPositionsListener: itemPositionsListener,
          ),
        ),

I realize a ScrollBar needs to have the same ScrollController as the scroll view it's wrapping, however, I'm not sure how to get this because ScrollablePositionedList doesn't have a ScrollController.

Errors in my terminal after running the project with the solution provided (little snippet of it):

Performing hot restart...                           
../../tools/flutter/.pub-cache/git/flutter.widgets-6
d6dac5f19b577338d912d3c9a45d26593e0a475/packages/scr
ollable_positioned_list/lib/src/scrollable_positione
d_list.dart:437:24: Warning: Operand of null-aware
operation '!' has type 'SchedulerBinding' which
excludes null.
Performing hot restart...                           
 - 'SchedulerBinding' is from
 'package:flutter/src/scheduler/binding.dart'
 ('../../tools/flutter/packages/flutter/lib/src/sche
 duler/binding.dart').
Performing hot restart...                           
      SchedulerBinding.instance!.addPostFrameCallbac
      k((_) {
Performing hot restart...                           
                       ^
Performing hot restart...                           
../../tools/flutter/.pub-cache/git/flutter.widgets-6
d6dac5f19b577338d912d3c9a45d26593e0a475/packages/scr
ollable_positioned_list/lib/src/scrollable_positione
d_list.dart:484:26: Warning: Operand of null-aware
operation '!' has type 'SchedulerBinding' which
excludes null.
Performing hot restart...                           
 - 'SchedulerBinding' is from
 'package:flutter/src/scheduler/binding.dart'
 ('../../tools/flutter/packages/flutter/lib/src/sche
 duler/binding.dart').
Performing hot restart...                           
        SchedulerBinding.instance!.addPostFrameCallb
        ack((_) {
Performing hot restart...                           
                         ^
Performing hot restart...                           
../../tools/flutter/.pub-cache/git/flutter.widgets-6
d6dac5f19b577338d912d3c9a45d26593e0a475/packages/scr
ollable_positioned_list/lib/src/positioned_list.dart
:298:24: Warning: Operand of null-aware operation
'!' has type 'SchedulerBinding' which excludes null.
Performing hot restart...                           
 - 'SchedulerBinding' is from
 'package:flutter/src/scheduler/binding.dart'
 ('../../tools/flutter/packages/flutter/lib/src/sche
 duler/binding.dart').
Performing hot restart...                           
      SchedulerBinding.instance!.addPostFrameCallbac
      k((_) {
Performing hot restart...                           
                       ^
Performing hot restart...                                               
Restarted application in 195ms.

After fixing the warnings (reply to comment), this now occurs randomly when using it:

The following assertion was thrown while notifying status listeners for AnimationController:
The Scrollbar's ScrollController has no ScrollPosition attached.
A Scrollbar cannot be painted without a ScrollPosition.
The Scrollbar attempted to use the provided ScrollController. This ScrollController should be
associated with the ScrollView that the Scrollbar is being applied to. When providing your
own
ScrollController, ensure both the Scrollbar and the Scrollable widget use the same one.

When the exception was thrown, this was the stack:
#0      RawScrollbarState._debugCheckHasValidScrollPosition.<anonymous closure>
(package:flutter/src/widgets/scrollbar.dart:1475:9)
#1      RawScrollbarState._debugCheckHasValidScrollPosition
(package:flutter/src/widgets/scrollbar.dart:1500:6)
#2      RawScrollbarState._validateInteractions
(package:flutter/src/widgets/scrollbar.dart:1445:14)
#3      AnimationLocalStatusListenersMixin.notifyStatusListeners
(package:flutter/src/animation/listener_helpers.dart:233:19)
#4      AnimationController._checkStatusChanged
(package:flutter/src/animation/animation_controller.dart:815:7)
#5      AnimationController._startSimulation
(package:flutter/src/animation/animation_controller.dart:749:5)
#6      AnimationController._animateToInternal
(package:flutter/src/animation/animation_controller.dart:612:12)
#7      AnimationController.reverse
(package:flutter/src/animation/animation_controller.dart:494:12)
#8      RawScrollbarState._maybeStartFadeoutTimer.<anonymous closure>
(package:flutter/src/widgets/scrollbar.dart:1630:37)
(elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and
dart:async-patch)

The AnimationController notifying status listeners was:
  AnimationController#72402(◀ 1.000)

Upvotes: 5

Views: 2794

Answers (3)

Abdulloh Razzoqov
Abdulloh Razzoqov

Reputation: 1

anyone who requires it can use this repo to access scrollController. This should only be done in pubspec.yaml

 scrollable_positioned_list:
git:
  url: https://github.com/nabil6391/flutter.widgets.git
  ref: master
  path: packages/scrollable_positioned_list/

And the result

    Scrollbar(
    thickness: 8,
    radius: Radius.circular(4),
    controller: itemScrollController.scrollController,
    child: ScrollablePositionedList.builder(
          itemCount: totalItems,
          itemScrollController: itemScrollController,
          itemBuilder: (context, index) {
            return Container(
                color: getItemColor(index, context),
                child: buildDropdownList(context, index),
            );
          },
      ),
 )

Upvotes: 0

Patrick
Patrick

Reputation: 3759

Use a ScrollConfiguration:

void main(List<String> args) {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: ScrollConfiguration(
          behavior: _ScrollbarBehavior(),
          child: ScrollablePositionedList.builder(
            itemCount: 100,
            itemBuilder: (context, index) => ListTile(title: Text('$index')),
          ),
        ),
      ),
    ),
  );
}

class _ScrollbarBehavior extends ScrollBehavior {
  @override
  Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) {
    return Scrollbar(child: child, controller: details.controller);
  }
}

Upvotes: 7

pmatatias
pmatatias

Reputation: 4434

You may see my old answer here for detail steps : https://stackoverflow.com/a/73279565/12838877

you can modify, but still have some bug when apply the ScrollController

try some alternative from issue#305, its not good enough but you can apply it.

final ItemScrollController itemSctr = ItemScrollController();
...

body: Scrollbar(
  controller: itemSctr.scrollController, 
  child: ScrollablePositionedList.builder(

Upvotes: 1

Related Questions