Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Scrollbar in vertical and horizontal axis

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;

enter image description here

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;

enter image description here

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?

like image 482
minathen Avatar asked Oct 23 '25 11:10

minathen


2 Answers

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.

enter image description here

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')),
                        ],
                      ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
like image 63
harlanx Avatar answered Oct 26 '25 00:10

harlanx


I was facing the same issue Than I created my own Package for it. I am personally using it in my Production apps. It is very easy to use. Handles the scrollbar and Thumb automatically But worry about that you can customize the scrollbar and Thumb according to your application Theme. Moreover its Works fine in All Platforms.

cross_scroll: ^0.0.75

You only 3 lines of code use it like below:

CrossScroll(
      child:///your child 
    )

Make sure your child has a specific height and width.

Maybe this package will also help you easily customize your thumb and scrolling track both horizontally and vertically

cross scroll package

enter image description here

like image 37
Mehran Ullah Avatar answered Oct 26 '25 01:10

Mehran Ullah