3

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?

minathen
  • 85
  • 1
  • 1
  • 9

4 Answers4

8

I suggest you to use InteractiveViewer for it's easier navigation when presenting large data on a table however to address your question you can actually do it without relying on any packages.

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')),
                        ],
                      ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
harlanx
  • 176
  • 3
  • 5
1

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

Mehran Ullah
  • 550
  • 4
  • 17
0

To anyone who needs a solution,

https://pub.dev/packages/adaptive_scrollbar#multiple-scrollbars

Use this package.

(Thanks to MuratWeny)

minathen
  • 85
  • 1
  • 1
  • 9
0

If you want to create costume list but have capability like table that can scroll horizontally then try this code.

 ScrollController _scrollControllerHorizontal = ScrollController();
 ScrollController _scrollControllerVertical = ScrollController();

 Widget MyListTable() {
   return Scrollbar(
       thumbVisibility: true,
       trackVisibility: true,
       controller: _scrollControllerVertical,
       child: SingleChildScrollView(
         controller: _scrollControllerVertical,
         scrollDirection: Axis.vertical,
         child: Scrollbar(
           thumbVisibility: true,
           trackVisibility: true,
           controller: _scrollControllerHorizontal,
           child: SingleChildScrollView(
             controller: _scrollControllerHorizontal,
             scrollDirection: Axis.horizontal,
             child: Wrap(
               direction: Axis.vertical,
               children: List.generate(
                 40,
                 (index) => Container(
                   width: 400,
                   height: 100,
                   color: Colors.blue,
                   margin: EdgeInsets.all(4),
                   child: Text("oke ${index}"),
                 ),
               ),
             ),
           ),
         ),
       ));
 }
 
mamena tech
  • 496
  • 5
  • 16