Skip to content

Commit e4f27cd

Browse files
authored
Add onHover callback support for TableRowInkWell (flutter#173373)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> - Add `onHover` parameter to `TableRowInkWell` - Add corresponding tests Issue: flutter#173370 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 6556337 commit e4f27cd

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

packages/flutter/lib/src/material/data_table.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class DataRow {
148148
this.selected = false,
149149
this.onSelectChanged,
150150
this.onLongPress,
151+
this.onHover,
151152
this.color,
152153
this.mouseCursor,
153154
required this.cells,
@@ -160,6 +161,7 @@ class DataRow {
160161
this.selected = false,
161162
this.onSelectChanged,
162163
this.onLongPress,
164+
this.onHover,
163165
this.color,
164166
this.mouseCursor,
165167
required this.cells,
@@ -200,6 +202,12 @@ class DataRow {
200202
/// that particular cell.
201203
final GestureLongPressCallback? onLongPress;
202204

205+
/// Called when a pointer enters or exits the row.
206+
///
207+
/// The boolean value passed to the callback is true if a pointer has entered the row and false
208+
/// when a pointer has exited the row.
209+
final ValueChanged<bool>? onHover;
210+
203211
/// Whether the row is selected.
204212
///
205213
/// If [onSelectChanged] is non-null for any row in the table, then
@@ -951,6 +959,7 @@ class DataTable extends StatelessWidget {
951959
required GestureTapCancelCallback? onTapCancel,
952960
required MaterialStateProperty<Color?>? overlayColor,
953961
required GestureLongPressCallback? onRowLongPress,
962+
required ValueChanged<bool>? onRowHover,
954963
required MouseCursor? mouseCursor,
955964
}) {
956965
final ThemeData themeData = Theme.of(context);
@@ -1007,10 +1016,11 @@ class DataTable extends StatelessWidget {
10071016
overlayColor: overlayColor,
10081017
child: label,
10091018
);
1010-
} else if (onSelectChanged != null || onRowLongPress != null) {
1019+
} else if (onSelectChanged != null || onRowLongPress != null || onRowHover != null) {
10111020
label = TableRowInkWell(
10121021
onTap: onSelectChanged,
10131022
onLongPress: onRowLongPress,
1023+
onHover: onRowHover,
10141024
overlayColor: overlayColor,
10151025
mouseCursor: mouseCursor,
10161026
child: label,
@@ -1223,6 +1233,7 @@ class DataTable extends StatelessWidget {
12231233
: () => row.onSelectChanged?.call(!row.selected),
12241234
overlayColor: row.color ?? effectiveDataRowColor,
12251235
onRowLongPress: row.onLongPress,
1236+
onRowHover: row.onHover,
12261237
mouseCursor:
12271238
row.mouseCursor?.resolve(states) ?? dataTableTheme.dataRowCursor?.resolve(states),
12281239
);
@@ -1276,6 +1287,7 @@ class TableRowInkWell extends InkResponse {
12761287
super.onDoubleTap,
12771288
super.onLongPress,
12781289
super.onHighlightChanged,
1290+
super.onHover,
12791291
super.onSecondaryTap,
12801292
super.onSecondaryTapDown,
12811293
super.overlayColor,

packages/flutter/test/material/data_table_test.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ void main() {
4747
onLongPress: () {
4848
log.add('onLongPress: ${dessert.name}');
4949
},
50+
onHover: (bool hovering) {
51+
if (hovering) {
52+
log.add('onHover: ${dessert.name}');
53+
}
54+
},
5055
cells: <DataCell>[
5156
DataCell(Text(dessert.name)),
5257
DataCell(
@@ -91,6 +96,15 @@ void main() {
9196
expect(log, <String>['onLongPress: Cupcake']);
9297
log.clear();
9398

99+
TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
100+
await gesture.addPointer(location: Offset.zero);
101+
addTearDown(gesture.removePointer);
102+
await tester.pump();
103+
await gesture.moveTo(tester.getCenter(find.text('Cupcake')));
104+
105+
expect(log, <String>['onHover: Cupcake']);
106+
log.clear();
107+
94108
await tester.tap(find.text('Calories'));
95109

96110
expect(log, <String>['column-sort: 1 true']);
@@ -123,7 +137,7 @@ void main() {
123137
expect(log, <String>['cell-tapDown: 375', 'cell-tapCancel: 375', 'cell-longPress: 375']);
124138
log.clear();
125139

126-
TestGesture gesture = await tester.startGesture(tester.getRect(find.text('375')).center);
140+
gesture = await tester.startGesture(tester.getRect(find.text('375')).center);
127141
await tester.pump(const Duration(milliseconds: 100));
128142
// onTapDown callback is registered.
129143
expect(log, equals(<String>['cell-tapDown: 375']));

0 commit comments

Comments
 (0)