I need to make the TableRow clickable and navigate to other screen but I cannot wrap TableRow with GestureDetector or Inkwell. How can I make the TableRow clickable. I have implemented as follows:
for (int i = 0; i < menuList.length; i++)
TableRow(children: [
SizedBox(
width: 5,
),
Text((i + 1).toString()),
Text(menuList[i].name),
Text(menuList[i].price.toString()),
Text(menuList[i].maxQty.toString()),
menuList[i].status == 0
? Text(
menuList[i].foodStatus,
style: TextStyle(color: Colors.red),
)
: YourListViewItem(
id: menuList[i].id,
index: menuList[i].status,
),
]),
I don't think you can do this,
You can use DataTable instead of Table widget, it will definitely meet your need.
In DataRow there is a property named onSelectChanged, This is
exactly what you want.
Not for the whole row, but for the individual cells in a row you can use TableRowInkWell. TableRowInkWell goes inside a TableRow itself, wrapping a child. Here is the answer, with credit to SoloWofl93: How to use TableRowInkWell inside Table in flutter?
Table(
border: TableBorder.all(),
children: [
TableRow(children: [
// HERE IT IS...
TableRowInkWell(
onTap: (){},
child: Column(children: [
Icon(
Icons.account_box,
size: iconSize,
),
Text('My Account'),
]),
),
Column(children: [
Icon(
Icons.settings,
size: iconSize,
),
Text('Settings')
]),
]),
],
)
It seems impossible to do this.
One thing you can try is adding inkwell to a table row of exactly the same size on top of the original table using a stack widget.
Related
I'm trying to use flexible on my text cause it's overflow but for some reason expanded or neither flexible didn't work. But it work on other text widget on different screen. Anyone know why ? How can I fix this ?
return Row(
children: [
/// Ticket Details
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Ticket Title
Flexible(
child: Text(
ticketData['title'],
style: primaryColor700Style.copyWith(
fontSize: fontSize18,
),
),
),
SizedBox(height: 8),
/// Date Created
Text(
'Created : ' +
DateFormat('d MMM y').format(
DateTime.parse(
ticketData['date_created'].toDate().toString(),
),
),
style: primaryColor400Style.copyWith(
fontSize: fontSize12,
),
),
],
),
/// Urgent Icon
if (ticketData['is_urgent'])
Icon(
Icons.warning_rounded,
size: 35,
color: warningColor,
),
],
);
Wrap the column with flexible
Row(
children: [
Flexible(
child: Column(
children:[
Text(),
]
)
)
]
)
Row takes infinite width, To get available width row for next children you can wrap Expanded/ Flexibile/ fixed width widget. You can check this doc more about.
You can find this from Layout algorithm on Row
Expanded, to indicate children that should take all the remaining room.
Flexible, to indicate children that should share the remaining room but that may by sized smaller (leaving some remaining room unused).
I'm trying to make a Table with two cells of the same width and height, so that the height depends on the size of the content. However, the smaller TableCell always shrinks:
This is what I'm trying to implement:
Here's the code:
Table(
children: [
TableRow(
children: [
TableCell(
child: Container(
color: Colors.green,
child: Text(
'long text long text long text long text long text long text long text'),
),
),
TableCell(
child: Container(
color: Colors.orange,
child: Text('short text'),
),
),
],
)
],
),
P.S. I could solve it by adding verticalAlignment: TableCellVerticalAlignment.fill, to the smaller cell, but any cell can be the smaller one, depending on the content. When I add this line to both cells, the whole table disappears. The only bypass I could imagine is to calculate the length of the content and find the smaller cell, but I wonder if there is a way to implement this UI directly with Flutter.
Would appreciate any help.
1. Row with IntrinsicHeight
IntrinsicHeight limits the height of the Row to the content size, which however is considered a 'relatively expensive' approach and is not recommended.
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
color: Colors.green,
child: Text(
'long text long text long text long text long text',
))),
Expanded(
child: Container(
color: Colors.orange,
child: Text(
'short text',
))),
],
),
),
2. Table with TableCellVerticalAlignment.fill
As mentioned in the question, the .fill option must not be used in the largest TableCell, because in this case the TableRow will have zero height. This is the preferred solution, because it doesn't have the 'expensiveness' issue of the previous one.
final texts = ['long text long text long text long text long text', 'short text'];
final colors = [Colors.green, Colors.orange];
// find the longest text and its index
final max = texts.asMap().entries.reduce(
(a, b) => (a.value.length > b.value.length) ? a : b,
);
return Table(children: [
TableRow(
children: texts
.asMap()
.entries
.map((e) => TableCell(
// use .fill in all cells except the largest
verticalAlignment: (e.key != max.key)
? TableCellVerticalAlignment.fill
: TableCellVerticalAlignment.top,
child: Container(
color: colors[e.key],
child: Text(e.value),
)))
.toList(),
),
]);
I am still new to coding, I have created multiple textbutton.icon's but they overflow. How do i stop the overflow. Even if i put is in a row or column it still overflows. I also would like to put more spacing between each row of buttons but that just makes it overflow more. Here is the multiple class code:
class home_buttons {
List<Widget> jeffButtons = [
Button1(),
Button2(),
Button3(),
Button4(),
Button5(),
Button6(),
Button7(),
Button8(),
Button9(),
];
}
Here is the button code:
class Button1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 9.0, 0.0, 0.0),
child: TextButton.icon(
onPressed: () => {},
icon: Column(
children: [
Icon(
Icons.search,
color: Colors.white,
size: 75,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
'Contact Us',
style: TextStyle(
color: Colors.white,
),
),
),
],
),
label: Text(
'', //'Label',
style: TextStyle(
color: Colors.white,
),
),
),
);
}
}
You can wrap your widgets with the SingleChildScrollView to enable scrolling.
Or if you want to fit the screen inside a Column or Row Widget you can wrap individual widgets with a Flexible Widget
Flutter listview normally have undefined height. The total height of listview is defined based on the items in the list. So when you declare listview directly you get overflow issue.
So as a solution you need to specify the height for the outer container, or use sizedbox to define the height.
Specifying height will solve your issue of overflow. To provide space between buttons you can also wrap that in a container and use the benefit of margin or padding to handle it efficiently.
Please find this code snippet to use Media to find height of device
Container(
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: SingleChildScrollView(
child: Column(
children: [
Here instead of SingleChildScrollView You can use listview or listbuilder which will solve your overflow issue
Hope this helps. Let me know If you want more details. Thanks
I have two rowCell's inside a Row widget in my app and I want to assign them different pages. I've tried putting the rowCell's in a GestureDetector, a FlatButton but neither of them have worked (as they should be linked to the Row widget and they need separate links for separate pages.)
Here is the part of my code:
...
new Divider(
height: _height / 20,
color: Colors.grey,
),
new Row(
children: <Widget>[
rowCell(10250, 'MEETUPS'),
rowCell(1520, 'FRIENDS'),
],
),
new Divider(height: _height / 20, color: Colors.grey),
...
Any solutions?
Just wrap the rowCell with GestureDetectorthen you will get separate onTap function with the same design.
Otherwise, you can use GestureDetector inside the rowCell(). And pass a function to the rowCell() to attach to the GestureDetector.
Widget rowSell(<your parameters>, Function onTapFunction) {
return GestureDetector(
onTap: onTapFunction,
child: <Your child>
),
}
And pass the function like:
new Row(
children: <Widget>[
rowCell(10250, 'MEETUPS', (){ <on Tap code> }),
rowCell(1520, 'FRIENDS', (){ <on Tap code> }),
],
),
The GestureDetector probably isn't working because you're wrapping it around the text and in that scenario, it's rare that it will work because you the onTap space is relative to space the text covers on the screen.
Try giving some padding inside the rowCell and then wrap it in a gesture detector, it will probably break your layout but at least you will know the problem and adjust accordingly.
Please try this...
If rowCell is return widget then wrap rowCell with GestureDetector and get click of that...
...
new Divider(
height: _height / 20,
color: Colors.grey,
),
new Row(
children: <Widget>[
GestureDetector(onTap: () {}, child: rowCell(10250, 'MEETUPS')),
GestureDetector(onTap: (){},child: rowCell(1520, 'FRIENDS')),
],
),
new Divider(height: _height / 20, color: Colors.grey),
...
From the comment from above you mention, I assume your rowCell function returns an Expanded widget.
So in rowCell function, inside Expanded widget add Inkwell widget. Also add one more argument which tells the page that you want to navigate to (onTap).
Widget rowCell(int count, String title, Widget navTo){
return Expanded(
child: Inkwell(
onTap: () => _navToPage(navTo)
child: .... //Your child widget
),
);
}
void _navToPage(Widget navTo){
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => navTo,
),
);
}
new Divider(height: _height / 20, color: Colors.grey),
new Row(
children: <Widget>[
GestureDetector(onTap: () {}, child: rowCell(10250, 'MEETUPS', MeetupsPage())),
GestureDetector(onTap: (){},child: rowCell(1520, 'FRIENDS', FriendsListPage())),
],
),
new Divider(height: _height / 20, color: Colors.grey),
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 ],
);
}