Related
I have a datatable with 4 columns but only 3 are currently showing when the screen is rotated i am able to see all 4 columns it is not even scrollable.
I am try to see the 4 columns in a single view ut I am getting this error:
lib/screens/home_screen.dart:79:29: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
DataTable(
^^^^^^^^^
lib/screens/home_screen.dart:78:54: Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.
const SingleChildScrollView(
^
/C:/src/flutter/flutter/packages/flutter/lib/src/widgets/single_child_scroll_view.dart:140:9: Context: Found this candidate, but the arguments don't match.
const SingleChildScrollView({
^^^^^^^^^^^^^^^^^^^^^
Restarted application in 274ms.
Here is th e code for the table:
ExpansionTile(
title: const Text("Click Here to See table Name"),
children: [
const SingleChildScrollView(
DataTable(
columns: const <DataColumn>[
DataColumn(
label: Text(
'Sr.No',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
DataColumn(
label: Text(
'Website',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
DataColumn(
label: Text(
'Tutorial',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
DataColumn(
label: Text(
'Review',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(
Text('1'),
),
DataCell(
Text('https://flutter.dev/'),
),
DataCell(
Text('Flutter'),
),
DataCell(
Text('5*'),
),
],
),
DataRow(
cells: <DataCell>[
DataCell(
Text('2'),
),
DataCell(
Text('https://dart.dev/'),
),
DataCell(
Text('Dart'),
),
DataCell(
Text('5*'),
),
],
),
DataRow(
cells: <DataCell>[
DataCell(
Text('3'),
),
DataCell(
Text('https://pub.dev/'),
),
DataCell(
Text('Flutter Packages'),
),
DataCell(
Text('5*'),
),
],
),
],
),
),
],
),
My question: How can make the table view in one screen so that it can be wrapped or the columns shrink to be view in a singleview?
You nee to pass DataTable to SingleChildScrollView's child, you forget to add child world also needed to pass scrollDirection too:
SingleChildScrollView(
scrollDirection: Axis.horizontal,// <---add this
child: DataTable(// <---add this
columns: <DataColumn>[
...
]
)
)
You have to define Datatable to child and if you are going to define more than one, you need to remove const in columns.
SingleChildScrollView(
child: DataTable( //Edited
columns: <DataColumn>[ //Edited
...
]
)
)
I have DataTable in flutter which is working fine until I got an empty list. In case the widget.detailDate.brands is empty, I get "Bad state: No element" error, now my question is, how can I handle the error, I've tried something like
widget.detailDate.brands.map((brand) => {
if (brand != ' '){
// do the DataRow stuff
}else{
print('brnad not found')
}
}).toList();
But it's not working. I wanna add something like "-", if the list is empty
My whole code looks like this:
DataTable buildBrandTable(context) {
return DataTable(
columnSpacing: 0,
showCheckboxColumn: false,
columns: const <DataColumn>[
DataColumn(
label: Text(
'Brand',
),
),
DataColumn(
label: Text(
'Mandant',
),
),
DataColumn(
label: Expanded(
child: Text(
'Januar',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'Februar',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'März',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'April',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'Mai',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'Juni',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'Juli',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'August',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'September',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'Oktober',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'November',
textAlign: TextAlign.end,
),
)),
DataColumn(
label: Expanded(
child: Text(
'Dezember',
textAlign: TextAlign.end,
),
),
),
],
rows: [
...widget.detailData.brands!
.map(
(brand) => DataRow(
onSelectChanged: (bool) {
Navigator.of(context)
.pushNamed(DetailScreen.routeName, arguments: {
'pageType': 'Brand',
'id': brand['brand_slug'].toString(),
});
},
color: (brand['brand'] == 'Gesamt')
? MaterialStateProperty.resolveWith(
(Set<MaterialState> states) => Colors.grey[300])
: null,
cells: [
DataCell(Text(brand['brand'])),
DataCell(Text(brand['mandant'])),
..._month
.map(
(month) => DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(formatter.format(brand[month])),
],
),
),
)
.toList(),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
formatter.format(
_month
.map((month) => brand[month])
.toList()
.reduce((a, b) => a + b),
),
),
],
),
),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text((brand['rate'] != null)
? formatterPercent.format(brand['rate'] / 100)
: 'N/A'),
],
),
),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text((brand['rate_letztes_jahr'] != null)
? formatterPercent
.format(brand['rate_letztes_jahr'] / 100)
: 'N/A')
],
),
),
],
),
)
.toList(),
],
);
}
I think your problem is caused by
rows: [
...widget.detailData.brands!
.map( // rest of your mapping function
...
maybe you should
widget.detailData.brands.length>0 ?
...widget.detailData.brands.map( // rest of your mapping function
:
[]
in your widget tree
Update
for example
Using the spread operator(...), adds the items individually not as a list
Column(
children: [
...values.map((value) {
return Text(value);
}),
],
),
I have a data table like below with three columns and I want to add vertical border separator , divider or whatever it called between all columns-included header- is this available in flutter datatables and how to do this ?
thanks
as a side note : I tried multiple options but it is hard to minuplate like listview or json_table package
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:talab/helpers/constant_helper.dart';
class TablesPage extends StatefulWidget {
#override
TablesPageState createState() => TablesPageState();
}
class TablesPageState extends State<TablesPage> {
// Generate a list of fiction prodcts
final List<Map> _products = List.generate(30, (i) {
return {"id": i, "name": "Product $i", "price": Random().nextInt(200) + 1};
});
int _currentSortColumn = 0;
bool _isAscending = true;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Kindacode.com'),
),
body: Container(
width: double.infinity,
child: SingleChildScrollView(
child: DataTable(
dividerThickness: 5,
decoration: BoxDecoration(
border:Border(
right: Divider.createBorderSide(context, width: 5.0),
left: Divider.createBorderSide(context, width: 5.0)
),
color: AppColors.secondaryColor,
),
showBottomBorder: true,
sortColumnIndex: _currentSortColumn,
sortAscending: _isAscending,
headingRowColor: MaterialStateProperty.all(Colors.amber[200]),
columns: [
DataColumn(label: Text('كود الطلب')
),
DataColumn(label: Text('الاشعار')),
DataColumn(
label: Text(
'التاريخ',
style: TextStyle(
color: Colors.blue, fontWeight: FontWeight.bold),
),),
],
rows: _products.map((item) {
return DataRow(cells: [
DataCell(Text(item['id'].toString())),
DataCell(Text(item['name'])),
DataCell(Text(item['price'].toString()))
]);
}).toList(),
),
),
));
}
}
As others have suggested, adding a vertical divider is one solution. Another is to use the DataTable's built-in border, which adds a border to every cell. It works like Border in the Decoration class. So, using your code example, the table can be defined:
DataTable(
border: TableBorder.all(
width: 5.0,
color:AppColors.secondaryColor,
dividerThickness: 5,
You can remove all of the other borders in your code. I believe this will give you the look you want.
As variant, you can use VerticalDivider widget. For example, define props of your vertical divider
Widget _verticalDivider = const VerticalDivider(
color: Colors.black,
thickness: 1,
);
and add it between header columns and cells
columns: [
DataColumn(label: Text('كود الطلب')),
DataColumn(label: _verticalDivider),
DataColumn(label: Text('الاشعار')),
DataColumn(label: _verticalDivider),
DataColumn(
label: Text(
'التاريخ',
style: TextStyle(
color: Colors.blue, fontWeight: FontWeight.bold),
),),
],
rows: _products.map((item) {
return DataRow(cells: [
DataCell(Text(item['id'].toString())),
DataCell(_verticalDivider),
DataCell(Text(item['name'])),
DataCell(_verticalDivider),
DataCell(Text(item['price'].toString()))
]);
}).toList(),
The following works for me:
DataTable(
showBottomBorder: true,
dividerThickness: 5.0,
columns: const <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(''),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(''),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('Albert')),
DataCell(VerticalDivider()),
DataCell(Text('19')),
DataCell(VerticalDivider()),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(VerticalDivider()),
DataCell(Text('43')),
DataCell(VerticalDivider()),
DataCell(Text('Professor')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('William')),
DataCell(VerticalDivider()),
DataCell(Text('27')),
DataCell(VerticalDivider()),
DataCell(Text('Associate Professor')),
],
),
],
)
I have dynamic List as shown below:
List<List<dynamic>> _userTransactionList;
The List contains these values:
[
[12.9, test, 80, 357.24, James],
[88.0, test, 19, 357.24, Carol],
[196.55, test, 34, 357.24, Matthew],
[48.0, test, 59, 357.24, Brown]
]
As shown above, my _userTransactionList length is 4. I need 3 column as:
Name Age Amount
And row cell will be:
Name Age Amount
James 80 12.9
Carol 19 88.0
Matthew 34 199.55
Brown 59 48.0
I can place the cell value manually as shown below, but I don't know how to get those value from list and add to row cells dynamically. Because of my List<List> _userTransactionList values comes from remote server I need to fill DataTable dynamically. Any idea?
Manual Code:
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columnSpacing: 30.0,
columns: <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Amount',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Mail',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
],
rows: <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('James')),
DataCell(Text('80')),
DataCell(Text('12.9')),
DataCell(
IconButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('James 80 12.9'),
),
);
},
icon: Icon(
Icons.email_outlined,
color: Colors.red,
),
),
),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Carol')),
DataCell(Text('19')),
DataCell(Text('88.0')),
DataCell(
IconButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Carol 19 88.0'),
),
);
},
icon: Icon(
Icons.email_outlined,
color: Colors.red,
),
),
),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Matthew')),
DataCell(Text('34')),
DataCell(Text('199.55')),
DataCell(
IconButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Matthew 34 199.55'),
),
);
},
icon: Icon(
Icons.email_outlined,
color: Colors.red,
),
),
),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Brown')),
DataCell(Text('59')),
DataCell(Text('48.0')),
DataCell(
IconButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Brown 59 48.0'),
),
);
},
icon: Icon(
Icons.email_outlined,
color: Colors.red,
),
),
),
],
),
],
),
);
Full Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: Text(_title)),
body: MyStatelessWidget(),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
List<List<dynamic>> _userTransactionList = [
[12.9, "BxC", 80, 357.24, "James"],
[88.0, "ArD", 19, 145.00, "Carol"],
[196.55, "VsT", 34, 18.60, "Matthew"],
[48.0, "IhO", 59, 92.19, "Brown"]
];
#override
Widget build(BuildContext context) {
List<DataRow> rows = [];
for (var i = 0; i < _userTransactionList.length; i++) {
rows.add(DataRow(cells: [
DataCell(
Text(_userTransactionList[i][4].toString()),
),
DataCell(
Text(_userTransactionList[i][2].toString()),
),
DataCell(
Text(_userTransactionList[i][0].toString()),
),
DataCell(
IconButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Matthew 34 199.55'),
),
);
},
icon: Icon(
Icons.email_outlined,
color: Colors.red,
),
),
),
]));
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
//child: _getData01(_userTransactionList, context)
child: DataTable(
columnSpacing: 30.0,
columns: <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Amount',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Mail',
style: TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold),
),
),
],
rows: rows,
));
}
}
I need to add the values to the data table, that values should be the values retreived from the textfield
Values are adding to data table , but now i want add multiple rows, the rows values are set throgh Textfield , and one more is how can i use dimissiable in Datatable
//Data table//
DataTable(
columns: <DataColumn>[
DataColumn(
label: Text("DATA"),
),
],
rows: <DataRow>[
DataRow(
cells:<DataCell> [
DataCell(
Text(_stext)
),
//TextField //
TextField(
controller: _controller,
maxLength: 8,
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: ()
{
_controller.clear();
},
icon: Icon(
Icons.clear,
color: Colors.black54,
),
),
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(20.0),
),
),
),),
Center(
child: RaisedButton(
onPressed: _onPressed,
color: Colors.redAccent,
child: Text('Add'),
),
),
Did you try this?
cells:<DataCell> [
DataCell(
Text(_controller.text)
),