flutter DataTable multiline wrapping and centering - flutter

I'm trying to have multiple, centered lines in the DataColumn() row of a DataTable() in flutter. It seems, though, that there is no support for centering or for multiple lines.
My DataTable Code looks something like this:
class TestDayData extends StatelessWidget {
final List<String> timesList = [
"This is",
"a bunch",
"of strings",
];
final String day;
TestDayData({Key key, this.day}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: DataTable(
showCheckboxColumn: false,
columns: [
DataColumn(
label: Center(child: Text(day)),
numeric: false,
),
],
rows: timesList
.map(
(times) => DataRow(cells: [
DataCell(
Text(times.toString()),
),
]),
)
.toList(),
),
);
}
}
I made a dartpad file here to show the above code in a larger context. (the reason that I am putting multiple DataTables in a Row widget, instead of using one DataTable for all of the days, is because I plan on putting each of them into a Stack widget so that I can overlay appointments on top of the columns.)
https://dartpad.dev/44bbb788e0d5f1e6393dd38a29430981
So far, I can approximate a multi-lined, centered DataColumn row by adding spaces and using a newline character as seen in the dartpad file. (but there has to be a better way!)

You are missing textAlign property in Text widget
DataTable(
showCheckboxColumn: false,
columns: [
DataColumn(
label: Center(child: Text(day, textAlign:TextAlign.center)),
numeric: false,
),
],
rows: timesList
.map((times) => DataRow(cells: [
DataCell(
Text(times.toString(), textAlign: TextAlign.center),
),
]),
)
.toList(),
),

You can try this to center your text in Datacolumn
DataColumn(
label: Center( widthFactor: 1.4,
child: Text("HELLO", textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0,),),)),
You can try this to center your text in Datacell for rows.
DataCell( Center(child: Text("Hello")))

For me on the DataColumn, using the Center widget or the textAlign property on the Text widget didn't work:
this is my solution:
DataColumn(
label: Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [Text("text")],
),
),
),
DataCell worked just fine with the Center widget

I figured out the solution.
you just need to wrap the text with Center widget and then wrap it again with Expanded widget just like this:
DataTable(
columns: [
DataColumn(label: Expanded(child: Center(child: Text('ID', textAlign: TextAlign.center,))),),
DataColumn(label: Expanded(child: Center(child: Text('name', textAlign: TextAlign.center,)))),
]
)

Related

flutter DataTable: columns and rows property not defined problem

I've started developing in Flutter with tables, but I met some problems with tables.
I use DataTable to represent data in a table. There is a problem that i face (The named parameter 'columns' isn't defined.
Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'columns'). it dos not recognize column's and rows property in DataTable widget. here is my code:
import 'package:flutter/material.dart';
class DataTable extends StatelessWidget {
#override
enter code heWidget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: DataTable(
columns: <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Designation',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('Mohit')),
DataCell(Text('23')),
DataCell(Text('Associate Software Developer')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Akshay')),
DataCell(Text('25')),
DataCell(Text('Software Developer')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Deepak')),
DataCell(Text('29')),
DataCell(Text('Team Lead ')),
],
),
],
),
),
);
Your class is named DataTable which clashes with the DataTable widget found in the material.dart.
Since dart first checks the current scope while resolving conflicts, the DataTable that you are using inside your build is referencing your own DataTable Stateless widget.
Rename it to MyDataTable, your issue will be fixed.
class MyDataTable extends StatelessWidget

Is it possible to make only the rows of DataTable widget scrollable?

I'm trying to implement a DataTable where the content is scrollable.
The issue is that the whole Table is scrollable, but I want the header to be static.
Does someone have an idea how to realize this?
Maybe two seperated DataTables? One just with the header and another scrollable one just with the content.
Though I think there must be a more elegant way to do this.
Here is my current, custom DataTable widget:
Widget _widgetDatatable(List<Client> clients) {
return Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child:
DataTable(
showCheckboxColumn: false,
columns: [
DataColumn(label: Text('Name')),
DataColumn(label: Text('First')),
DataColumn(label: Text('Date Birth')),
DataColumn(label: Text('Date Moved In')),
],
rows: clients
.map(
(e) => DataRow(
onSelectChanged: (value) {
bloc.dataRowKlientSingleClicked(e);
},
selected: e.clickedInDataTable,
cells: [
DataCell(Text(e.lastName)),
DataCell(Text(e.firstName)),
DataCell(
Text(format(e.dateOfBirth)),
),
DataCell(
Text(format(e.dateMovedIn)),
),
]),
)
.toList()),
),);
}
At the moment, there is no option to do this with the DataTable widget. But luckily, there is a package that implements a table that can do just that: table_sticky_headers.

TextOverFlow Flutter

I have a certain Text widget , when it overflows I have 3 options. Either fade ,visible, ellipsis or clip. But I don't want to choose between them . I want if a text has overflow then don't show the text.
Edit :
I'm working on a code clone to this design
Assuming that the textStyle is unknown.
How could I achieve that?
Code:
class SwipeNavigationBar extends StatefulWidget {
final Widget child;
SwipeNavigationBar({this.child});
#override
_SwipeNavigationBarState createState() => _SwipeNavigationBarState();
}
class _SwipeNavigationBarState extends State<SwipeNavigationBar> {
#override
Widget build(BuildContext context) {
return Consumer<Controller>(
builder: (_, _bloc, __) {
return SafeArea(
child: AnimatedContainer(
duration: Duration(seconds: 01),
color: Colors.white,
curve: Curves.easeIn,
height: !_bloc.x ? 50 : 200,
child: Row(
children: [
Column(
verticalDirection: VerticalDirection.up,
children: [
Expanded(child: Icon(Icons.dashboard)),
Expanded(
child: RotatedBox(
quarterTurns: -45,
child: Text(
'data',
softWrap: false,
style: TextStyle(
textBaseline: TextBaseline.alphabetic
),
),
),
),
],
)
],
),
),
);
},
);
}
}
To mimic the design you might want to look into using the Stack widget. However, to answer your question, you'd want to set softWrap to false.
Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 100,
child: Text(
'Some text we want to overflow',
softWrap: false,
),
),
)
softWrap is really the key here. Although, I added the Align and SizedBox widgets to allow this to be used anywhere, regardless of what parent widget you are using (since some widgets set tight constraints on their children and will override their children's size preference).
CodePen Example
Edit: 5/6/2020
With the release of Flutter v1.17 you now have access to a new Widget called NavigationRail which may help you with the design you're looking for.
Use ternary operator to check the length of the text that you are passing to the Text widget and based on that pass the text itself or an empty string.
String yourText;
int desiredLengthToShow = 10; //Change this according to you.
...
Text(
child: yourText.length > desiredLengthToShow ? "" : yourText,
);

How to change DataTable's column width in Flutter?

I have a DataTable in my Flutter app. The problem is that when data is filled, the width of the columns is set automatically, and it too large. How can I manually set the column width? I tried to change the width parameters in the "Widget build", but it change the width of the whole table, but not a desired column.
Add columnSpacing property to DataTable. By default it is set to 56.0.
columnSpacing: 30.0
#Smith, you mean you can't do this ? if you could share some code ...
Widget build(BuildContext context) {
return Scaffold(
body: DataTable(
columns: [DataColumn(label: Text('label'))],
rows: [
DataRow(cells: [DataCell(
Container(
width: 200, //SET width
child: Text('text')))
])
]
),
);
use columnSpacing in the databale then set 1 this takes then length of column text
columnSpacing: 0,
Better than using Container as per the accepted answer, use ConstrainedBox so that the cell size will only increase if the contents is equal to or exceeds the constrained width.
import 'package:flutter/material.dart';
void main() async {
runApp(
MaterialApp(
home: Scaffold(
body: Card(
child: DataTable(columns: [
DataColumn(
label: Text(
'short text column'.toUpperCase(),
style: TextStyle(fontWeight: FontWeight.bold),
)),
DataColumn(
label: Text(
'long text column'.toUpperCase(),
style: TextStyle(fontWeight: FontWeight.bold),
)),
], rows: [
DataRow(cells: [
DataCell(Text('short text')),
DataCell(ConstrainedBox(
constraints: BoxConstraints(maxWidth: 250), //SET max width
child: Text('very long text blah blah blah blah blah blah',
overflow: TextOverflow.ellipsis))),
]),
DataRow(cells: [
DataCell(Text('short text')),
DataCell(ConstrainedBox(
constraints: BoxConstraints(maxWidth: 250), //SET max width
child: Text('very long text blah blah blah blah blah blah',
overflow: TextOverflow.ellipsis))),
])
]),
),
),
),
);
}
View Dartpad example

How do you center the label in a Flutter DataColumn widget?

I can center the DataCell in a DataRow but how do you do it for the DataColumn label?
I want the first DataColumn left justified and the rest centered. Wrapping the label in a Center widget does not take effect.
new DataColumn(
label: Center(
child: Text(statName,textAlign: TextAlign.center,
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),),
)
);
Found how:
DataColumn(
label: Expanded(
child: Text(
'Label',
textAlign: TextAlign.center,
))),
You may want to wrap the contents of the Label in a Center widget. There's also an Align widget that uses alignment: Alignment.center and your Text as it's child.
This is how i resolved this issue :
DataColumn(
label: Center(
widthFactor: 5.0, // You can set as per your requirement.
child: Text(
'View',
style: style_16_bold_primary,
),
),
),
I had the same problem and solved the issue by commenting the following code section in data_table.dart file.
if (onSort != null) {
final Widget arrow = _SortArrow(
visible: sorted,
down: sorted ? ascending : null,
duration: _sortArrowAnimationDuration,
);
const Widget arrowPadding = SizedBox(width: _sortArrowPadding);
label = Row(
textDirection: numeric ? TextDirection.rtl : null,
children: <Widget>[ label, arrowPadding, arrow ],
);
}