Reputation: 3274
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
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
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
Reputation: 4434
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