flutterdartflutter-layoutflutter-web

DataTable that expands to window with, and also scroll horizontally if it overflows


I'm trying to create a DataTable that will expand to the available width of its parent as DataTables do normally, but also if there isn't enough horizontal space on the screen it should allow horizontal scrolling. As it stands I'm only able to do one or the other. The problem is when I allow the table to scroll horizontally, the cells no longer expand. And when I allow the cells to expand horizontally, the table will be cut off of the page if it doesn't fit.

Sample code below is of the table version where the cells won't expand, but scrolling works.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ScrollController verticalController = ScrollController();
  ScrollController horizontalController = ScrollController();

  bool maximized = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Scrollbar(
          controller: verticalController,
          isAlwaysShown: true,
          child: SingleChildScrollView(
            controller: verticalController,
            child: Padding(
              padding: const EdgeInsets.all(15.0),
              child: Column(
                children: [
                  Text('Table Name'),
                  Container(
                    width: double.infinity,
                    child: Scrollbar(
                      isAlwaysShown: true,
                      controller: horizontalController,
                      child: SingleChildScrollView(
                        controller: horizontalController,
                        scrollDirection: Axis.horizontal,
                        child: DataTable(
                            dataRowHeight: 50,
                            columnSpacing: 20,
                            horizontalMargin: 0,
                            columns: List<DataColumn>.generate(
                                10,
                                (index) => DataColumn(
                                    label: Text("Column" + index.toString()))),
                            rows: List<DataRow>.generate(10, (rowIndex) {
                              if (maximized) {
                                return DataRow(
                                  cells: List<DataCell>.generate(
                                    10,
                                    (cellIndex) => DataCell(
                                      Container(
                                        width: 100,
                                        child: Column(
                                          children: [
                                            Text("row" + rowIndex.toString()),
                                            Text("Cell" + cellIndex.toString()),
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                );
                              } else {
                                return DataRow(
                                  cells: List<DataCell>.generate(
                                    10,
                                    (cellIndex) => DataCell(
                                      Container(
                                        child: Column(
                                          children: [
                                            Text("row" + rowIndex.toString()),
                                            Text("Cell" + cellIndex.toString()),
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                );
                              }
                            })),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ));
  }
}

Solution

  • I was able to fix this issue by using a constrained box around my table and setting the minimum width to the available width on the screen. This still allows the table to expand horizontally while keeping the width at least as large as the available screen width.