Background: I am currently working on a sticky data table, currently I have two DataTable widget in a Row as shown by the code below.
...Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// produce left rows
if (fixedLeftColumns > 0)
Container(
decoration: BoxDecoration(
color: Styles.defaultLightWhiteColor,
boxShadow: [Styles.defaultBoxShadow]),
child: DataTable(
showCheckboxColumn: false,
dividerThickness: 0.5,
columns: leftFixedHeaders
.map((e) => DataColumn(
onSort: e.onSort,
tooltip:
e.onSort == null ? null : e.label,
label: Container(
alignment: Alignment.centerLeft,
height: rowHeight,
width: e.width - 10,
child: CustomText(text: e.label)),
))
.toList(),
rows: [...leftFixedRows.map((e) => e)],
),
),
// produce table rows
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: dataScrollController,
child: DataTable(
showCheckboxColumn: false,
dividerThickness: 0.5,
columns: centerFixedHeaders
.map((e) => DataColumn(
onSort: e.onSort,
tooltip:
e.onSort == null ? null : e.label,
label: Container(
alignment: Alignment.centerLeft,
height: rowHeight,
width: e.width,
child: CustomText(text: e.label)),
))
.toList(),
rows: [...centerFixedRows.map((e) => e)],
),
)),
],
),
)
The sticky data table works quite well here, however I encountered a problem with this setup. When I hover into a row of the sticky table, it only highlights the row of the sticky table, however, I would like for the center table also to be highlighted on hovered or pressed.
Currently (cursor hovering the sticky table):
Expectations:
Is there any way to link both table rows to update simultaneously by hovering one? Or are there any other alternatives to produce this result?
I managed to find a workaround to produce hovering the whole row when on DataTable side by side by using MouseRegion
.
Using MouseRegion
First I added the MouseRegion
widget inside my DataCell and a new variable isHoveredIndex
. When a movement of onEnter was found, set the to the index of the cell row isHoveredIndex = index
. Clear the variable onExit to stop highlighting.
I also needed to set the columnSpacing and horizontalMargin of DataTable to 0 and replace these spacing and margin manually in the DataCell, added with Column and Row so the MouseRegion's size will expand to the whole cell instead of just fitting a text's size.
...DataTable(
showCheckboxColumn: false,
horizontalMargin: 0,
columnSpacing: 0,
dividerThickness: 0.5,
...
int? isHoveredIndex;
...DataCell(MouseRegion(
onEnter: (_) {
setState(() {
isHoveredIndex = index;
});
},
onExit: (event) {
setState(() {
isHoveredIndex = null;
});
},
child: Container(
padding: EdgeInsets.only(
left:
leftRow.first == e ? horizontalMargin : columnSpacing,
right:
leftRow.last == e ? horizontalMargin : columnSpacing),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
e.child,
],
),
],
),
),
))
...DataRow(
...
color: isHoveredIndex == index
? WidgetStateProperty.all(
Colors.grey.withOpacity(0.2))
: null