Fix selection menu not showing after clear (#37042)
This allows the text selection menu to be shown after deleting all text in a text field.
This commit is contained in:
parent
53a1f225ae
commit
d82bca2a31
@ -1061,7 +1061,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
return;
|
||||
}
|
||||
if (value.text != _value.text) {
|
||||
_hideSelectionOverlayIfNeeded();
|
||||
hideToolbar();
|
||||
_showCaretOnScreen();
|
||||
if (widget.obscureText && value.text.length == _value.text.length + 1) {
|
||||
_obscureShowCharTicksPending = _kObscureShowLatestCharCursorTicks;
|
||||
@ -1300,11 +1300,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
}
|
||||
}
|
||||
|
||||
void _hideSelectionOverlayIfNeeded() {
|
||||
_selectionOverlay?.hide();
|
||||
_selectionOverlay = null;
|
||||
}
|
||||
|
||||
void _updateOrDisposeSelectionOverlayIfNeeded() {
|
||||
if (_selectionOverlay != null) {
|
||||
if (_hasFocus) {
|
||||
@ -1323,7 +1318,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
// EditableWidget, not just changes triggered by user gestures.
|
||||
requestKeyboard();
|
||||
|
||||
_hideSelectionOverlayIfNeeded();
|
||||
_selectionOverlay?.hide();
|
||||
_selectionOverlay = null;
|
||||
|
||||
if (widget.selectionControls != null) {
|
||||
_selectionOverlay = TextSelectionOverlay(
|
||||
|
@ -16,7 +16,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'editable_text_utils.dart';
|
||||
import 'semantics_tester.dart';
|
||||
|
||||
final TextEditingController controller = TextEditingController();
|
||||
TextEditingController controller;
|
||||
final FocusNode focusNode = FocusNode(debugLabel: 'EditableText Node');
|
||||
final FocusScopeNode focusScopeNode = FocusScopeNode(debugLabel: 'EditableText Scope Node');
|
||||
const TextStyle textStyle = TextStyle();
|
||||
@ -29,6 +29,12 @@ enum HandlePositionInViewport {
|
||||
void main() {
|
||||
setUp(() {
|
||||
debugResetSemanticsIdCounter();
|
||||
controller = TextEditingController();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
controller.dispose();
|
||||
controller = null;
|
||||
});
|
||||
|
||||
// Tests that the desired keyboard action button is requested.
|
||||
@ -528,7 +534,7 @@ void main() {
|
||||
equals('TextInputAction.done'));
|
||||
});
|
||||
|
||||
testWidgets('can only show toolbar when there is text and a selection', (WidgetTester tester) async {
|
||||
testWidgets('can show toolbar when there is text and a selection', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: EditableText(
|
||||
@ -545,17 +551,12 @@ void main() {
|
||||
final EditableTextState state =
|
||||
tester.state<EditableTextState>(find.byType(EditableText));
|
||||
|
||||
// Can't show the toolbar when there's no focus.
|
||||
expect(state.showToolbar(), false);
|
||||
await tester.pump();
|
||||
expect(find.text('PASTE'), findsNothing);
|
||||
|
||||
controller.text = 'blah';
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), false);
|
||||
await tester.pump();
|
||||
expect(find.text('PASTE'), findsNothing);
|
||||
|
||||
// Select something. Doesn't really matter what.
|
||||
// Can show the toolbar when focused even though there's no text.
|
||||
state.renderEditable.selectWordsInRange(
|
||||
from: const Offset(0, 0),
|
||||
cause: SelectionChangedCause.tap,
|
||||
@ -564,6 +565,58 @@ void main() {
|
||||
expect(state.showToolbar(), true);
|
||||
await tester.pump();
|
||||
expect(find.text('PASTE'), findsOneWidget);
|
||||
|
||||
// Hide the menu again.
|
||||
state.hideToolbar();
|
||||
await tester.pump();
|
||||
expect(find.text('PASTE'), findsNothing);
|
||||
|
||||
// Can show the menu with text and a selection.
|
||||
controller.text = 'blah';
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
await tester.pump();
|
||||
expect(find.text('PASTE'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('can show the toolbar after clearing all text', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/35998.
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: EditableText(
|
||||
backgroundCursorColor: Colors.grey,
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
style: textStyle,
|
||||
cursorColor: cursorColor,
|
||||
selectionControls: materialTextSelectionControls,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final EditableTextState state =
|
||||
tester.state<EditableTextState>(find.byType(EditableText));
|
||||
|
||||
// Add text and an empty selection.
|
||||
controller.text = 'blah';
|
||||
await tester.pump();
|
||||
state.renderEditable.selectWordsInRange(
|
||||
from: const Offset(0, 0),
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
// Clear the text and selection.
|
||||
expect(find.text('PASTE'), findsNothing);
|
||||
state.updateEditingValue(const TextEditingValue(
|
||||
text: '',
|
||||
));
|
||||
await tester.pump();
|
||||
|
||||
// Should be able to show the toolbar.
|
||||
expect(state.showToolbar(), true);
|
||||
await tester.pump();
|
||||
expect(find.text('PASTE'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Fires onChanged when text changes via TextSelectionOverlay', (WidgetTester tester) async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user