Skip to content

Commit 4e8e8c4

Browse files
authored
[two_dimensional_scrollables] Add regression test (#11376)
Fixes flutter/flutter#137112 This PR adds a regression test for flutter/flutter#137112, where TableView would crash when focusing a widget outside of the table while a previously focused TextField inside the table was scrolled out of view. While this issue appears to have been resolved by changes in the Flutter framework specifically flutter/flutter#135182 which addressed how focus keeps children alive in two-dimensional scrollables, this PR adds a dedicated test case to the package to ensure this behavior does not regress. ## Pre-Review Checklist **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. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 7ae082a commit 4e8e8c4

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

packages/two_dimensional_scrollables/test/table_view/table_test.dart

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4175,6 +4175,105 @@ void main() {
41754175
);
41764176
},
41774177
);
4178+
4179+
testWidgets(
4180+
'Table does not crash when focusing outside of the table while focused text field is not in the view',
4181+
(WidgetTester tester) async {
4182+
// Regression test for https://github.com/flutter/flutter/issues/137112
4183+
final verticalController = ScrollController();
4184+
final horizontalController = ScrollController();
4185+
addTearDown(() {
4186+
verticalController.dispose();
4187+
horizontalController.dispose();
4188+
});
4189+
4190+
await tester.pumpWidget(
4191+
MaterialApp(
4192+
home: Scaffold(
4193+
body: Column(
4194+
children: [
4195+
const TextField(key: Key('outside_textfield')),
4196+
Expanded(
4197+
child: TableView.builder(
4198+
verticalDetails: ScrollableDetails.vertical(
4199+
controller: verticalController,
4200+
),
4201+
horizontalDetails: ScrollableDetails.horizontal(
4202+
controller: horizontalController,
4203+
),
4204+
cellBuilder:
4205+
(BuildContext context, TableVicinity vicinity) {
4206+
return TableViewCell(
4207+
child: Center(
4208+
child: TextField(
4209+
key: Key(
4210+
'cell_${vicinity.row}_${vicinity.column}',
4211+
),
4212+
),
4213+
),
4214+
);
4215+
},
4216+
columnCount: 20,
4217+
columnBuilder: (int index) {
4218+
return const TableSpan(
4219+
foregroundDecoration: TableSpanDecoration(
4220+
border: TableSpanBorder(trailing: BorderSide()),
4221+
),
4222+
extent: FixedTableSpanExtent(100),
4223+
);
4224+
},
4225+
rowCount: 40,
4226+
rowBuilder: (int index) {
4227+
return TableSpan(
4228+
backgroundDecoration: TableSpanDecoration(
4229+
color: index.isEven ? Colors.purple[100] : null,
4230+
border: const TableSpanBorder(
4231+
trailing: BorderSide(width: 3),
4232+
),
4233+
),
4234+
extent: const FixedTableSpanExtent(50),
4235+
);
4236+
},
4237+
),
4238+
),
4239+
],
4240+
),
4241+
),
4242+
),
4243+
);
4244+
4245+
// 1. Select a TextField in the table.
4246+
// Use the vicinity from the original crash report.
4247+
const vicinity = TableVicinity(row: 5, column: 6);
4248+
final Finder cellTextField = find.byKey(
4249+
Key('cell_${vicinity.row}_${vicinity.column}'),
4250+
);
4251+
// Bring it into view.
4252+
verticalController.jumpTo(250);
4253+
horizontalController.jumpTo(600);
4254+
await tester.pumpAndSettle();
4255+
4256+
await tester.tap(cellTextField);
4257+
await tester.pumpAndSettle();
4258+
expect(FocusManager.instance.primaryFocus, isNotNull);
4259+
4260+
// 2. Scroll until it disappears from the view, without unfocusing it.
4261+
verticalController.jumpTo(verticalController.offset + 1000);
4262+
await tester.pumpAndSettle();
4263+
4264+
// 3. Select another TextField outside of the table.
4265+
final Finder outsideTextField = find.byKey(
4266+
const Key('outside_textfield'),
4267+
);
4268+
await tester.tap(outsideTextField);
4269+
await tester.pumpAndSettle();
4270+
4271+
// 4. Scroll back and ensure the table does not crash.
4272+
verticalController.jumpTo(verticalController.offset - 1000);
4273+
await tester.pumpAndSettle();
4274+
expect(cellTextField, findsOneWidget);
4275+
},
4276+
);
41784277
}
41794278

41804279
class _NullBuildContext implements BuildContext, TwoDimensionalChildManager {

0 commit comments

Comments
 (0)