I have two scrollbars in my flutter project for scrolling the data table. Here are the codes.
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: MediaQuery.of(context).size.width * (1 / 2),
height: MediaQuery.of(context).size.height * (1 / 2),
child: Scrollbar(
isAlwaysShown: true,
controller: _controllerOne,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: _controllerOne,
child: Scrollbar(
controller: _controllerTwo,
isAlwaysShown: true,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _controllerTwo,
child: DataTable(
...
),
),
))))));
}
These two scrollbars are working correctly. But I can not see both of them at the same time. I mean if I write the Scrollbar with scrollDirection in vertical first it's like;
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: MediaQuery.of(context).size.width * (1 / 2),
height: MediaQuery.of(context).size.height * (1 / 2),
child: Scrollbar(
isAlwaysShown: true,
controller: _controllerOne,
child: SingleChildScrollView(
**scrollDirection: Axis.vertical,**
controller: _controllerOne,
child: Scrollbar(
controller: _controllerTwo,
isAlwaysShown: true,
child: SingleChildScrollView(
**scrollDirection: Axis.horizontal,**
controller: _controllerTwo,
child: DataTable(
...
),
),
))))));
}
if I write the Scrollbar with scrollDirection in horizontal first it's like;
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: MediaQuery.of(context).size.width * (1 / 2),
height: MediaQuery.of(context).size.height * (1 / 2),
child: Scrollbar(
isAlwaysShown: true,
controller: _controllerOne,
child: SingleChildScrollView(
**scrollDirection: Axis.horizontal,**
controller: _controllerOne,
child: Scrollbar(
controller: _controllerTwo,
isAlwaysShown: true,
child: SingleChildScrollView(
**scrollDirection: Axis.vertical,**
controller: _controllerTwo,
child: DataTable(
...
),
),
))))));
}
When I scroll till the end I can see the other scrollbar for both directions. But when the table is shown I need to see them both at the same time.
Is there any solution for this?
Old suggestion:
I suggest you to use InteractiveViewer.builder for its easier navigation when presenting large data on a table
New suggestion: (in regard to latest flutter version)
Flutter has recently released the widget TableView.builder from their official package two_dimensional_scrollables which has built in scrollbar support for both axis (enabled by default for desktop build) and has a similar structure when creating DataTable so you'll have no trouble migrating. Here's a great example on how to use it.
However, to address your question you can actually do it without relying on any packages and please note that those I mentioned before are more performant as they support lazy loading.
What you'll have to do is nest the vertical and horizontal SingleChildScrollView and wrap it with two ScrollBar then attach a ScrollController respectively and use the notificationPredicate property on the inner ScrollBar.
class MyWidget extends StatelessWidget {
final List<int> shades = [100, 200, 300, 400, 500, 600, 700, 800, 900];
final ScrollController _horizontal = ScrollController(),
_vertical = ScrollController();
@override
Widget build(BuildContext context) {
return SizedBox(
height: 500,
width: 400,
child: Scrollbar(
controller: _vertical,
thumbVisibility: true,
trackVisibility: true,
child: Scrollbar(
controller: _horizontal,
thumbVisibility: true,
trackVisibility: true,
notificationPredicate: (notif) => notif.depth == 1,
child: SingleChildScrollView(
controller: _vertical,
child: SingleChildScrollView(
controller: _horizontal,
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Preview')),
DataColumn(label: Text('Color')),
DataColumn(label: Text('Shade')),
],
rows: [
for (var color in Colors.primaries)
for (var shade in shades)
DataRow(
cells: [
DataCell(Container(
height: 20, width: 50, color: color[shade])),
DataCell(Text(color.toString())),
DataCell(Text('$shade')),
],
),
],
),
),
),
),
),
);
}
}