I have a DataTable with a SingleChildScrollView and it works fine. I can scroll it horizontally, works perfect.
My question is; assume that I want to keep the ID
column fixed, and I want to scroll horizontally only the other columns. How can I do this?
Here my code works fully horizontal:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Map> _books = [
{
'id': 100,
'title': 'Flutter',
'author': 'David Micheal'
},
{
'id': 102,
'title': 'Git and GitHub',
'author': 'Mike Nick'
},
{
'id': 101,
'title': 'Android Basics',
'author': 'Dave John'
},
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('DataTable Demo'),
),
body: ListView(
children: [
_createDataTable()
],
),
),
);
}
DataTable _createDataTable() {
return DataTable(columns: _createColumns(), rows: _createRows());
}
List<DataColumn> _createColumns() {
return [
DataColumn(label: Text('ID')),
DataColumn(label: Text('Book')),
DataColumn(label: Text('Author')),
DataColumn(label: Text('Category')),
DataColumn(label: Text('Category')),
DataColumn(label: Text('Category'))
];
}
List<DataRow> _createRows() {
return _books
.map((book) => DataRow(cells: [
DataCell(Text('#' book['id'].toString())),
DataCell(Text(book['title'])),
DataCell(Text(book['author'])),
DataCell(FlutterLogo()),
DataCell(FlutterLogo()),
DataCell(FlutterLogo())
]))
.toList();
}
}
CodePudding user response:
For this, you have to use horizontal_data_table: ^4.1.1 plugin
https://pub.dev/packages/horizontal_data_table/install
CodePudding user response:
I'm not sure where you are stuck, but you can simply create a Row
widget. The widget of the Row
should render your sticky column and the second widget should be an Expanded
wrapping your SingleChildScrollView
.
The implementation should look something like this:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Map> _books = [
{'id': 100, 'title': 'Flutter', 'author': 'David Micheal'},
{'id': 102, 'title': 'Git and GitHub', 'author': 'Mike Nick'},
{'id': 101, 'title': 'Android Basics', 'author': 'Dave John'},
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('DataTable Demo'),
),
body: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: _getTable(),
),
),
);
}
Row _getTable() {
final stickyCells = _books.map(
(e) => {
"id": e["id"],
},
);
final rows = _books.map(
(e) => {
"title": e["title"],
"author": e["author"],
},
);
return Row(
children: [
StickyColumnWidget(
cells: stickyCells,
),
Expanded(
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
child: Column(
children: [
...rows.map(
(r) => RowWidget(
row: r,
),
),
],
),
),
),
],
);
}
}
class StickyColumnWidget extends StatelessWidget {
final Iterable<Map> cells;
const StickyColumnWidget({
Key? key,
required this.cells,
}) : super(key: key);
@override
Widget build(BuildContext context) {
//create a column widget with cells
}
}
class RowWidget extends StatelessWidget {
final Map row;
const RowWidget({
Key? key,
required this.row,
}) : super(key: key);
@override
Widget build(BuildContext context) {
//return your original datatable row
}
}
Try out and see if it works out for you.