I get this error when using the AppBar:
The Scrollbar's ScrollController has no ScrollPosition attached.
This is my CustomScrollBar:
class CustomScrollBar extends StatelessWidget {
final Widget child;
final ScrollController scrollController;
const CustomScrollBar({
required this.scrollController,
required this.child,
});
#override
Widget build(BuildContext context) {
return RawScrollbar(
thumbColor: AppColors.gray,
radius: Radius.circular(8),
thickness: 4,
isAlwaysShown: true,
controller: scrollController,
child: child,
);
}
}
I should be always visible. And this is how I use it:
child: CustomScrollBar(
scrollController: _scrollControllerForScrollBar,
child: SingleChildScrollView(
controller: _scrollControllerForScrollBar,
child: Padding(
padding: EdgeInsets.all(7.0.scaled),
child: Container(
width: double.infinity,
child: Text(
'any text bla bla bla \n\n\n this is a lot of \n text \n .'
),
),
),
),
),
As you can see both the ScrollBar and the SingleChildScrollView use the same ScrollController. I have no idea why this error occurs. Any idea what I am missing here?
I was using a ScrollBar with a ListView widget and was getting this error in the debug console. To get rid of it, I had to set the ScrollController on both widgets.
final yourScrollController = ScrollController();
Scrollbar(
isAlwaysShown: true,
thickness: 10,
controller: yourScrollController, // Here
child: ListView.builder(
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
controller: yourScrollController, // AND Here
itemCount: yourRecordList?.length
....
)
)
Let's assume you're using both Scrollbar widget and ListView widget as a child of the scrollbar - Both of them should have the same controller as :
ScrollController _controller = ScrollController();
Scrollbar(
controller: _controller,
child: ListView(
controller: _controller,
....), // ListView
) // Scrollbar
Remove the scrollController entirely and that should fix the problem. that is how I fixed my code so your code should look something like this
class CustomScrollBar extends StatelessWidget {
final Widget child;
const CustomScrollBar({
required this.child,
});
#override
Widget build(BuildContext context) {
return RawScrollbar(
thumbColor: AppColors.gray,
radius: Radius.circular(8),
thickness: 4,
isAlwaysShown: true,
child: child,
);
}
}
and the second part should be like this
child: CustomScrollBar(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(7.0.scaled),
child: Container(
width: double.infinity,
child: Text(
'any text bla bla bla \n\n\n this is a lot of \n text \n .'
),
),
),
),
),
The following assertion was thrown during a scheduler callback:
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.
This is flutter's bug, https://github.com/flutter/flutter/issues/82573.
It is fixed on the flutter master branch:
flutter channel master
flutter upgrade
If you use nested scroller like this:
Expanded(
flex: 2,
child: Center(
child: Scrollbar(
child: SingleChildScrollView(
primary: true,
child: Scrollbar(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
.....)
You can fix the issue adding this line to first Scrollable view:
primary: true
The UI plotter wants know start position for the scroller both on mobile and low resolutions on desktop with size:
MediaQuery.of(context).size.shortestSide < 600
For this error, you have to define same 1 scrollController for both ScrollBar and SingleSchildScrollView/ListView:
For example from my prj:
final ScrollController _scrollController = ScrollController(); //define just 1 controller
final _currencyFormatter = NumberFormat('#,##0.00', 'vi_VN');
final double _safeSpaceToShowToolTip = 1.4;
final double _fixedChartHeight = 350.0;
int _touchedIndex = -1;
#override
Widget build(BuildContext context) {
return Scrollbar(
controller: _scrollController, // and use it both here
isAlwaysShown: true,
trackVisibility: true,
radius: Radius.circular(6.0),
child: SingleChildScrollView(
controller: _scrollController, // AND HERE
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
child: Container(
margin: EdgeInsets.only(bottom: R.dimens.mediumSpacing),
height:
R.dimens.getSpecificSize(_fixedChartHeight, isForHeight: true),
width: R.dimens
.getSpecificSize(_fixedChartHeight * 1.9, isForHeight: false),
child: BarChart(
_barChartData(),
),
),
),
);
}
Related
I am attempting to have a horizontal gallery of elements which probably extends beyond the edges of the view so it needs to be horizontally scrollable. I have this. (This is primarily for a desktop app)
The elements in the gallery should be draggable but only for vertical dragging so that the user can place them somewhere else.
I've tried various approaches including a listener. Below seems to get closest to what I need, however, the picture elements are draggable in all directions. What I would like is when the user starts dragging them in a horizontal direction, instead of them being draggable, the gesture/control passes to the parent listview. So basically user can drag horizontally to scroll, and vertically to pull elements out of the gallery.
With current code, the user can scroll the listview by clicking and dragging between the elements, it seems the gesture detector never calls the onHorizontalDragStart (or onHorizontalDragUpdate.
(I have also tried with two nested GestureDetectors, one around the listview, and one around the PictElementDisplay but that didn't seem to make much sense.)
class PictGalleryView extends StatelessWidget {
PictGalleryView({
Key? key,
required this.size,
}) : super(key: key);
final Size size;
final projectSettings = GetIt.I<ProjectSettings>();
ScrollController _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return SizedBox(
height: size.height,
width: size.width,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
dragDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
},
),
child: ListView.builder(
controller: _scrollController,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: projectSettings.numPictElements,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(5),
child: Center(
child: GestureDetector(
onHorizontalDragStart: (details) {
dev.log('onHorizontalDragStart');
// this doesn't happen?
},
child: PictElementDisplay(
//this shouldn't be horizontally draggable but it is!
element: projectSettings.pictElementDataList[index],
size: Size(75, 60),
),
),
),
);
},
),
),
);
}
}
//...
class PictElementDisplay extends StatelessWidget {
PictElementDisplay({
Key? key,
required this.element,
required this.size,
}) : super(key: key);
final PictElementData element;
final Size size;
#override
Widget build(BuildContext context) {
return SizedBox.fromSize(
child: Draggable(
data: element,
feedback: Container(
height: size.height,
width: size.width,
decoration: const BoxDecoration(
color: Colors.green, //todo
),
child: Text('id: ${element.id.toString()}'),
),
child: Container(
height: size.height,
width: size.width,
decoration: const BoxDecoration(
color: Colors.red, //todo
),
child: Text('id: ${element.id.toString()}'),
),
),
);
}
}
(and ChatGPT doesn't seem to quite know how to do it either. :-) ). Thanks in advance.
The GestureDetector has to be inside the Draggable then it can be used to override the default behaviour. In this use-case, you can pass in the ScrollControler associated with the parent ListView as a parameter to be modified which can control the listview. If you want to use the PictElementDisplay in different contexts and the override to only apply when it appears in the gallery, you can make the widget nullable and add logic only to change the behaviour when the scroll controller is present i.e.
class PictElementDisplay extends StatelessWidget {
PictElementDisplay({
required this.element,
required this.size,
this.scrollController,
});
final PictElementData element;
final Size size;
final ScrollController? scrollController;
#override
Widget build(BuildContext context) {
Widget listChild = Container(
height: size.height,
width: size.width,
decoration: const BoxDecoration(
color: Colors.red, //todo
),
child: Text('id: ${element.id.toString()}'),
);
Widget gestureWidget = GestureDetector(
onHorizontalDragUpdate: (details) {
// Pass the control to the parent ListView to handle horizontal scrolling
dev.log('onHorizontalDragUpdate ${details.toString()}');
scrollController?.jumpTo(scrollController!.offset - details.delta.dx);
},
onTap: () {
//E.g. add to currently active page without needing to drag it
dev.log('tapped ${element.id}');
},
child: listChild,
);
Widget draggableChildWidget =
(scrollController != null) ? gestureWidget : listChild;
return SizedBox.fromSize(
child: Draggable(
data: element,
feedback: Container(
height: size.height,
width: size.width,
decoration: const BoxDecoration(
color: Colors.green, //todo
),
child: Text('id: ${element.id.toString()}'),
),
child: draggableChildWidget,
),
);
}
}
and in the parent level
#override
Widget build(BuildContext context) {
return SizedBox(
height: widget.size.height,
width: widget.size.width,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
dragDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
},
),
child: ListView.builder(
controller: scrollController,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: projectSettings.numPictElements,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
PictElementData element =
projectSettings.pictElementDataList[index];
Size size = Size(75, 60);
return Padding(
padding: const EdgeInsets.all(5),
child: Center(
child: PictElementDisplay(
element: element,
size: size,
// scrollController allows the widget to
// override its own horizontal dragging
scrollController: scrollController,
),
),
);
},
),
),
);
}
I am trying to make UI of calculator based on my drawing,
here I have divided screen in two expanded container, top one for output and bottom one for buttons...
in bottom container I have taken grid view to show all buttons,
I want to fit all button's in bottom area without having scrolling effect of grid view.
in my code...grid view not showing last row...I have to scroll down to view it...
here is my code
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(child: Container(color: Colors.orange,)),
Expanded(
child: GridView.builder(
itemCount: buttons.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemBuilder: (context, index) {
return ButtonWidget(color: Colors.grey,
ontap: () {},
caption: buttons[index].toString(),
textcolor: Colors.black);
})),
],
),
),
);
}
and here is button's class
class ButtonWidget extends StatelessWidget {
final color;
final textcolor;
final String caption;
final VoidCallback ontap;
const ButtonWidget(
{Key? key,
required this.color,
required this.ontap,
required this.caption,
required this.textcolor})
: super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(100),
),
child: Center(
child: Text(
caption.toString(),
style: GoogleFonts.actor(fontSize: 30,fontWeight: FontWeight.bold),
)),
),
);
}
}
1.Remove your Expanded for GridView.
Disable scrolling for GridView.
Like this.
GridView.builder(
/// Add these two lines
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
/// Your code,
),
Tip:
If you don't wanna have small container on top, you can resize buttons' aspect ratio like this. But it will make buttons look a bit ugly.
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
///Add this, tweak the value as you wish
childAspectRatio: 1.3,
),
Have Fun!
This is my Widget:
// the category selector widget
class CategorySelector extends StatefulWidget {
const CategorySelector({Key? key}) : super(key: key);
#override
_CategorySelectorState createState() => _CategorySelectorState();
}
class _CategorySelectorState extends State<CategorySelector> {
// categories
List<String> categories = ['Messages', 'Online', 'Groups', 'Requests'];
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
height: 80,
alignment: Alignment.centerLeft, // FIXME: doesn't work
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) {
return Text(categories[index]);
},
),
),
);
}
}
Current Output
The issue is that ListView.builder items not getting aligned in the center inside a container with scroll direction horizontal. I want to align the ListView items in the center left. May I know how can I do it?
As I know, ListView always get the full size of her parent height/width depends on scrollDirection. That's we need to define listview height/width. For yours, scrollDirection are horizontal, so the solution is
Container(
color: Colors.blue,
height: 80,
alignment: Alignment.center, // FIXME: does it work for you?
child: Container(
height: 14,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) {
return Text(categories[index], style: TextStyle(fontSize: 14),);
},
),
),
)
I am trying to achieve a very common behavior nowadays which is to have a horizontal List within another widget that is at the same time scrollable. Think something like the home screen of the IMDb app:
So I want to have a widget that scrolls vertically with few items on them. At the top of it, there should be a horizontal ListView, followed up with some items called motivationCard. There are some headers in between the list and the cards as well.
I got something like this on my Widget:
#override
Widget build(BuildContext context) => BlocBuilder<HomeEvent, HomeState>(
bloc: _homeBloc,
builder: (BuildContext context, HomeState state) => Scaffold(
appBar: AppBar(),
body: Column(
children: <Widget>[
Text(
Strings.dailyTasks,
),
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: tasks.length,
itemBuilder: (BuildContext context, int index) =>
taskCard(
taskNumber: index + 1,
taskTotal: tasks.length,
task: tasks[index],
),
),
Text(
Strings.motivations,
),
motivationCard(
motivation: Motivation(
title: 'Motivation 1',
description:
'this is a description of the motivation'),
),
motivationCard(
motivation: Motivation(
title: 'Motivation 2',
description:
'this is a description of the motivation'),
),
motivationCard(
motivation: Motivation(
title: 'Motivation 3',
description:
'this is a description of the motivation'),
),
],
),
),
);
this is the error I get:
I/flutter (23780): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (23780): The following assertion was thrown during performResize():
I/flutter (23780): Horizontal viewport was given unbounded height.
I/flutter (23780): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter (23780): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter (23780): vertical space in which to expand.
I have tried:
Wrapping the ListView with an Expanded widget
Wrapping the Column with SingleChildScrollView > ConstrainedBox > IntrinsicHeight
Having CustomScrollView as a parent, with a SliverList and the List within a SliverChildListDelegate
None of these work and I continue getting the same kind of error. This is a very common thing and shouldn't be any hard, somehow I just cannot get it to work :(
Any help would be much appreciated, thanks!
Edit:
I thought this could help me but it didn't.
Well, Your Code Work Fine with wrapping your- ListView.builder with Expanded Widget &
setting mainAxisSize: MainAxisSize.min, of Column Widget.
E.x Code of what you Have.
body: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Headline',
style: TextStyle(fontSize: 18),
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 15,
itemBuilder: (BuildContext context, int index) => Card(
child: Center(child: Text('Dummy Card Text')),
),
),
),
Text(
'Demo Headline 2',
style: TextStyle(fontSize: 18),
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (ctx,int){
return Card(
child: ListTile(
title: Text('Motivation $int'),
subtitle: Text('this is a description of the motivation')),
);
},
),
),
],
),
Update:
Whole page Is Scroll-able with - SingleChildScrollView.
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Headline',
style: TextStyle(fontSize: 18),
),
SizedBox(
height: 200.0,
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 15,
itemBuilder: (BuildContext context, int index) => Card(
child: Center(child: Text('Dummy Card Text')),
),
),
),
Text(
'Demo Headline 2',
style: TextStyle(fontSize: 18),
),
Card(
child: ListTile(title: Text('Motivation $int'), subtitle: Text('this is a description of the motivation')),
),
Card(
child: ListTile(title: Text('Motivation $int'), subtitle: Text('this is a description of the motivation')),
),
Card(
child: ListTile(title: Text('Motivation $int'), subtitle: Text('this is a description of the motivation')),
),
Card(
child: ListTile(title: Text('Motivation $int'), subtitle: Text('this is a description of the motivation')),
),
Card(
child: ListTile(title: Text('Motivation $int'), subtitle: Text('this is a description of the motivation')),
),
],
),
),
Screenshot:
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: 7,
itemBuilder: (_, i) {
if (i < 2)
return _buildBox(color: Colors.blue);
else if (i == 3)
return _horizontalListView();
else
return _buildBox(color: Colors.blue);
},
),
);
}
Widget _horizontalListView() {
return SizedBox(
height: 120,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (_, __) => _buildBox(color: Colors.orange),
),
);
}
Widget _buildBox({Color color}) => Container(margin: EdgeInsets.all(12), height: 100, width: 200, color: color);
}
We have to use SingleScrollView inside another SingleScrollView, using ListView will require fixed height
SingleChildScrollView(
child: Column(
children: <Widget>[
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [Text('H1'), Text('H2'), Text('H3')])),
Text('V1'),
Text('V2'),
Text('V3')]))
If someone gets the renderview port was exceeded error. warp your ListView in a Container widget and give it the height and width property to fix the issue
Column(
children: <Widget>[
Text(
Strings.dailyTasks,
),
Container(
height: 60,
width: double.infinity,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: tasks.length,
itemBuilder: (BuildContext context, int index) =>
taskCard(
taskNumber: index + 1,
taskTotal: tasks.length,
task: tasks[index],
),
),
)
]
)
I tried in this code and I fixed my problem I hope solved your want it.
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
item(),
item(),
item(),
item(),
],
),
),
Horizontal ListView inside Vertical ListView using Builder
None of the answers proved to solve my issue, which was to have a horizontal ListView inside a Vertical ListView while still using ListBuilder (which is more performant than simply rendering all child elements at once).
Turned out it was rather simple. Simply wrap your vertical list child inside a Column, and check if index is 0 (or index % 3 == 0) then render the horizontal list.
Seems to work fine:
final verticalListItems = [];
final horizontalListItems = [];
ListView.builder(
shrinkWrap: true,
itemCount: verticalListItems.length,
itemBuilder: (context, vIndex) {
final Chat chat = verticalListItems[vIndex];
return Column( // Wrap your child inside this column
children: [
// And then conditionally render your Horizontal list
if (vIndex == 0) ListView.builder(itemCount: horizontalListItems.length itemBuilder: (context, hIndex) => Text('Horizontal List $hIndex')),
// Vertical list
Text('Item No. $vIndex')
],
);
},
),
for Web Chome you have to add MaterialScrollBehavior for horizontal scrolling to work. see(Horizontal listview not scrolling on web but scrolling on mobile) I demonstrate how to use the scrollcontroller to animate the list both left and right.
import 'package:flutter/gestures.dart';
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
#override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
return MaterialApp(
title: 'Flutter Demo',
scrollBehavior: MyCustomScrollBehavior(),
)
class TestHorizontalListView extends StatefulWidget {
TestHorizontalListView({Key? key}) : super(key: key);
#override
State<TestHorizontalListView> createState() => _TestHorizontalListViewState();
}
class _TestHorizontalListViewState extends State<TestHorizontalListView> {
List<String> lstData=['A','B','C','D','E','F','G'];
final ScrollController _scrollcontroller = ScrollController();
_buildCard(String value)
{
return Expanded(child:Container(
margin: const EdgeInsets.symmetric(vertical: 20.0),
width:300,height:400,child:Card(child: Expanded(child:Text(value,textAlign: TextAlign.center, style:TextStyle(fontSize:30))),)));
}
void _scrollRight() {
_scrollcontroller.animateTo(
_scrollcontroller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
}
void _scrollLeft() {
_scrollcontroller.animateTo(
0,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
}
_segment1()
{
return SingleChildScrollView(child:
Expanded(child:
Container(height:300,
width:MediaQuery.of(context).size.width,
child:Row(children: [
FloatingActionButton.small(onPressed: _scrollRight, child: const Icon(Icons.arrow_right),),
Expanded(child:Scrollbar(child:ListView.builder(
itemCount: lstData.length,
controller: _scrollcontroller,
scrollDirection: Axis.horizontal,
itemBuilder:(context,index)
{
return _buildCard(lstData[index]);
})
,),
),
FloatingActionButton.small(onPressed: _scrollLeft, child: const Icon(Icons.arrow_left),),
]))
,
)
);
}
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text("horizontal listview",)),body:
segment1(),
);
}
}
You just have to fix your height of your Listview (by wrapping it in a SizedBox for example).
This is because the content of your listview can't be known before the frame is drawn. Just imagine a list of hundreds of items.. There is no way to directly know the maximum height among all of them.
Is there any way to show the scroll indicator on the ListView?
Here is my basic code:
ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => ListTile(title: Text("Item= ${index + 1}"),),
)
Thanks to Günter Zöchbauer.
You can wrap your ListView in Scrollbar
Scrollbar(
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => ListTile(title: Text("Item= ${index + 1}"),),),
)
I think better to use CupertinoScrollbar instead of Scrollbar. CupertinoScrollbar is can touch and scroll to the bottom..
Ex:
CupertinoScrollbar(
child: ListView.builder(...),
Or
Scrollbar(
child: ListView.builder(...),
You can implement this designer scrollbar library :
draggable_scrollbar
alphabet scrolling
OR
You can wrap ListView in Scrollbar widget
Scrollbar(
child: ListView.builder(...),
)
Create a ScrollController variable (ScrollController _scrollController);
Instatiate _scrollController inside initState() or wherever you want, _scrollController = ScrollController();
Add _scrollController variable inside Scrollbar and ListView properties,
controller:_scrollController
Here's the code:
ScrollController _scrollController;
#override
void initState() {
super.initState();
_scrollController = ScrollController();
}
Scrollbar(
isAlwaysShown: true,
controller: _scrollController,
child: ListView(
controller: _scrollController,
)
if you don't want it always shown set to false
thumbVisibility: false,
Scrollbar(
thickness: 10,
isAlwaysShown: true,
child: ListView.builder(
itemCount: _controller().transactonsList.length,
itemBuilder: (context, index) {
return Card(
elevation: 5,
child: Container(
padding: const EdgeInsets.only(bottom: 16),
height: 80,
child: Row(
children: [
SizedBox(width: 10),
amountOfTransaction(index),
SizedBox(width: 16),
dateAndTitleOfTransaction(index),
],
),
),
);
},
),
)
final ScrollController _scroll = ScrollController();
#override
Widget build(BuildContext context) {
(...)
child: ListView.builder(
controller: _scroll,
)
}
If u need to style your scroll bar a bit wrap the ListView in RawScrollbar and use the same scroll controller instance for both widgets
final ScrollController _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
(...)
child: RawScrollbar(
controller: _scrollController,
thumbColor: Colors.redAccent,
radius: const Radius.circular(8),
crossAxisMargin: 2,
child: ListView.builder(
controller: _scrollController,
itemCount: 50,
itemBuilder: (context, index) => ListTile(
title: Text("Item= ${index + 1}"),
),
),
),
}
Scrollbar(
child:ListView.builder(
itemCount:20,
itemBuilder:(c,i) => MyItem(i),
),
),
You have to give itemcount as how many list you have
-----Example: itemCount: items.length,-----