Skip to content

Commit 5ef9b84

Browse files
authored
Expose toggle to textfield's opacity animation. (#122474)
Expose toggle to textfield's opacity animation.
1 parent 100cf21 commit 5ef9b84

File tree

5 files changed

+74
-7
lines changed

5 files changed

+74
-7
lines changed

packages/flutter/lib/src/cupertino/text_field.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ class CupertinoTextField extends StatefulWidget {
263263
this.cursorWidth = 2.0,
264264
this.cursorHeight,
265265
this.cursorRadius = const Radius.circular(2.0),
266+
this.cursorOpacityAnimates = true,
266267
this.cursorColor,
267268
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
268269
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
@@ -394,6 +395,7 @@ class CupertinoTextField extends StatefulWidget {
394395
this.cursorWidth = 2.0,
395396
this.cursorHeight,
396397
this.cursorRadius = const Radius.circular(2.0),
398+
this.cursorOpacityAnimates = true,
397399
this.cursorColor,
398400
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
399401
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
@@ -660,6 +662,9 @@ class CupertinoTextField extends StatefulWidget {
660662
/// {@macro flutter.widgets.editableText.cursorRadius}
661663
final Radius cursorRadius;
662664

665+
/// {@macro flutter.widgets.editableText.cursorOpacityAnimates}
666+
final bool cursorOpacityAnimates;
667+
663668
/// The color to use when painting the cursor.
664669
///
665670
/// Defaults to the [DefaultSelectionStyle.cursorColor]. If that color is
@@ -818,6 +823,7 @@ class CupertinoTextField extends StatefulWidget {
818823
properties.add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0));
819824
properties.add(DoubleProperty('cursorHeight', cursorHeight, defaultValue: null));
820825
properties.add(DiagnosticsProperty<Radius>('cursorRadius', cursorRadius, defaultValue: null));
826+
properties.add(DiagnosticsProperty<bool>('cursorOpacityAnimates', cursorOpacityAnimates, defaultValue: true));
821827
properties.add(createCupertinoColorProperty('cursorColor', cursorColor, defaultValue: null));
822828
properties.add(FlagProperty('selectionEnabled', value: selectionEnabled, defaultValue: true, ifFalse: 'selection disabled'));
823829
properties.add(DiagnosticsProperty<TextSelectionControls>('selectionControls', selectionControls, defaultValue: null));
@@ -1318,7 +1324,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
13181324
cursorHeight: widget.cursorHeight,
13191325
cursorRadius: widget.cursorRadius,
13201326
cursorColor: cursorColor,
1321-
cursorOpacityAnimates: true,
1327+
cursorOpacityAnimates: widget.cursorOpacityAnimates,
13221328
cursorOffset: cursorOffset,
13231329
paintCursorAboveText: true,
13241330
autocorrectionTextRectColor: selectionColor,

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ class TextField extends StatefulWidget {
293293
this.cursorWidth = 2.0,
294294
this.cursorHeight,
295295
this.cursorRadius,
296+
this.cursorOpacityAnimates,
296297
this.cursorColor,
297298
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
298299
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
@@ -581,6 +582,9 @@ class TextField extends StatefulWidget {
581582
/// {@macro flutter.widgets.editableText.cursorRadius}
582583
final Radius? cursorRadius;
583584

585+
/// {@macro flutter.widgets.editableText.cursorOpacityAnimates}
586+
final bool? cursorOpacityAnimates;
587+
584588
/// The color of the cursor.
585589
///
586590
/// The cursor indicates the current location of text insertion point in
@@ -863,6 +867,7 @@ class TextField extends StatefulWidget {
863867
properties.add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0));
864868
properties.add(DoubleProperty('cursorHeight', cursorHeight, defaultValue: null));
865869
properties.add(DiagnosticsProperty<Radius>('cursorRadius', cursorRadius, defaultValue: null));
870+
properties.add(DiagnosticsProperty<bool>('cursorOpacityAnimates', cursorOpacityAnimates, defaultValue: null));
866871
properties.add(ColorProperty('cursorColor', cursorColor, defaultValue: null));
867872
properties.add(DiagnosticsProperty<Brightness>('keyboardAppearance', keyboardAppearance, defaultValue: null));
868873
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('scrollPadding', scrollPadding, defaultValue: const EdgeInsets.all(20.0)));
@@ -1248,7 +1253,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
12481253

12491254
TextSelectionControls? textSelectionControls = widget.selectionControls;
12501255
final bool paintCursorAboveText;
1251-
final bool cursorOpacityAnimates;
1256+
bool? cursorOpacityAnimates = widget.cursorOpacityAnimates;
12521257
Offset? cursorOffset;
12531258
final Color cursorColor;
12541259
final Color selectionColor;
@@ -1262,7 +1267,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
12621267
forcePressEnabled = true;
12631268
textSelectionControls ??= cupertinoTextSelectionHandleControls;
12641269
paintCursorAboveText = true;
1265-
cursorOpacityAnimates = true;
1270+
cursorOpacityAnimates ??= true;
12661271
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? cupertinoTheme.primaryColor;
12671272
selectionColor = selectionStyle.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40);
12681273
cursorRadius ??= const Radius.circular(2.0);
@@ -1274,7 +1279,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
12741279
forcePressEnabled = false;
12751280
textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls;
12761281
paintCursorAboveText = true;
1277-
cursorOpacityAnimates = false;
1282+
cursorOpacityAnimates ??= false;
12781283
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? cupertinoTheme.primaryColor;
12791284
selectionColor = selectionStyle.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40);
12801285
cursorRadius ??= const Radius.circular(2.0);
@@ -1291,23 +1296,23 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
12911296
forcePressEnabled = false;
12921297
textSelectionControls ??= materialTextSelectionHandleControls;
12931298
paintCursorAboveText = false;
1294-
cursorOpacityAnimates = false;
1299+
cursorOpacityAnimates ??= false;
12951300
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
12961301
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
12971302

12981303
case TargetPlatform.linux:
12991304
forcePressEnabled = false;
13001305
textSelectionControls ??= desktopTextSelectionHandleControls;
13011306
paintCursorAboveText = false;
1302-
cursorOpacityAnimates = false;
1307+
cursorOpacityAnimates ??= false;
13031308
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
13041309
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
13051310

13061311
case TargetPlatform.windows:
13071312
forcePressEnabled = false;
13081313
textSelectionControls ??= desktopTextSelectionHandleControls;
13091314
paintCursorAboveText = false;
1310-
cursorOpacityAnimates = false;
1315+
cursorOpacityAnimates ??= false;
13111316
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
13121317
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
13131318
handleDidGainAccessibilityFocus = () {

packages/flutter/lib/src/widgets/editable_text.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,11 +1487,13 @@ class EditableText extends StatefulWidget {
14871487
/// {@endtemplate}
14881488
final Radius? cursorRadius;
14891489

1490+
/// {@template flutter.widgets.editableText.cursorOpacityAnimates}
14901491
/// Whether the cursor will animate from fully transparent to fully opaque
14911492
/// during each cursor blink.
14921493
///
14931494
/// By default, the cursor opacity will animate on iOS platforms and will not
14941495
/// animate on Android platforms.
1496+
/// {@endtemplate}
14951497
final bool cursorOpacityAnimates;
14961498

14971499
///{@macro flutter.rendering.RenderEditable.cursorOffset}

packages/flutter/test/cupertino/text_field_test.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,31 @@ void main() {
381381
},
382382
);
383383

384+
testWidgets('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async {
385+
386+
// True
387+
388+
await tester.pumpWidget(
389+
const CupertinoApp(
390+
home: CupertinoTextField(autofocus: true),
391+
),
392+
);
393+
await tester.pump();
394+
EditableText editableText = tester.widget(find.byType(EditableText));
395+
expect(editableText.cursorOpacityAnimates, true);
396+
397+
// False
398+
399+
await tester.pumpWidget(
400+
const CupertinoApp(
401+
home: CupertinoTextField(autofocus: true, cursorOpacityAnimates: false),
402+
),
403+
);
404+
await tester.pump();
405+
editableText = tester.widget(find.byType(EditableText));
406+
expect(editableText.cursorOpacityAnimates, false);
407+
});
408+
384409
testWidgets(
385410
'takes available space horizontally and takes intrinsic space vertically',
386411
(WidgetTester tester) async {

packages/flutter/test/material/text_field_test.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,35 @@ void main() {
571571
expect(state.widget.cursorColor, cursorColor);
572572
});
573573

574+
testWidgets('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async {
575+
576+
// True
577+
578+
await tester.pumpWidget(
579+
const MaterialApp(
580+
home: Material(
581+
child: TextField(autofocus: true, cursorOpacityAnimates: true),
582+
),
583+
),
584+
);
585+
await tester.pump();
586+
EditableText editableText = tester.widget(find.byType(EditableText));
587+
expect(editableText.cursorOpacityAnimates, true);
588+
589+
// False
590+
591+
await tester.pumpWidget(
592+
const MaterialApp(
593+
home: Material(
594+
child: TextField(autofocus: true, cursorOpacityAnimates: false),
595+
),
596+
),
597+
);
598+
await tester.pump();
599+
editableText = tester.widget(find.byType(EditableText));
600+
expect(editableText.cursorOpacityAnimates, false);
601+
});
602+
574603
testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
575604
final SemanticsTester semantics = SemanticsTester(tester);
576605
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;

0 commit comments

Comments
 (0)