Expose toggle to textfield's opacity animation. (#122474)

Expose toggle to textfield's opacity animation.
This commit is contained in:
Benjamin Quinn 2023-03-23 15:49:58 -04:00 committed by GitHub
parent 100cf21e27
commit 5ef9b847aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 7 deletions

View file

@ -263,6 +263,7 @@ class CupertinoTextField extends StatefulWidget {
this.cursorWidth = 2.0,
this.cursorHeight,
this.cursorRadius = const Radius.circular(2.0),
this.cursorOpacityAnimates = true,
this.cursorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
@ -394,6 +395,7 @@ class CupertinoTextField extends StatefulWidget {
this.cursorWidth = 2.0,
this.cursorHeight,
this.cursorRadius = const Radius.circular(2.0),
this.cursorOpacityAnimates = true,
this.cursorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
@ -660,6 +662,9 @@ class CupertinoTextField extends StatefulWidget {
/// {@macro flutter.widgets.editableText.cursorRadius}
final Radius cursorRadius;
/// {@macro flutter.widgets.editableText.cursorOpacityAnimates}
final bool cursorOpacityAnimates;
/// The color to use when painting the cursor.
///
/// Defaults to the [DefaultSelectionStyle.cursorColor]. If that color is
@ -818,6 +823,7 @@ class CupertinoTextField extends StatefulWidget {
properties.add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0));
properties.add(DoubleProperty('cursorHeight', cursorHeight, defaultValue: null));
properties.add(DiagnosticsProperty<Radius>('cursorRadius', cursorRadius, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('cursorOpacityAnimates', cursorOpacityAnimates, defaultValue: true));
properties.add(createCupertinoColorProperty('cursorColor', cursorColor, defaultValue: null));
properties.add(FlagProperty('selectionEnabled', value: selectionEnabled, defaultValue: true, ifFalse: 'selection disabled'));
properties.add(DiagnosticsProperty<TextSelectionControls>('selectionControls', selectionControls, defaultValue: null));
@ -1318,7 +1324,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
cursorHeight: widget.cursorHeight,
cursorRadius: widget.cursorRadius,
cursorColor: cursorColor,
cursorOpacityAnimates: true,
cursorOpacityAnimates: widget.cursorOpacityAnimates,
cursorOffset: cursorOffset,
paintCursorAboveText: true,
autocorrectionTextRectColor: selectionColor,

View file

@ -293,6 +293,7 @@ class TextField extends StatefulWidget {
this.cursorWidth = 2.0,
this.cursorHeight,
this.cursorRadius,
this.cursorOpacityAnimates,
this.cursorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
@ -581,6 +582,9 @@ class TextField extends StatefulWidget {
/// {@macro flutter.widgets.editableText.cursorRadius}
final Radius? cursorRadius;
/// {@macro flutter.widgets.editableText.cursorOpacityAnimates}
final bool? cursorOpacityAnimates;
/// The color of the cursor.
///
/// The cursor indicates the current location of text insertion point in
@ -863,6 +867,7 @@ class TextField extends StatefulWidget {
properties.add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0));
properties.add(DoubleProperty('cursorHeight', cursorHeight, defaultValue: null));
properties.add(DiagnosticsProperty<Radius>('cursorRadius', cursorRadius, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('cursorOpacityAnimates', cursorOpacityAnimates, defaultValue: null));
properties.add(ColorProperty('cursorColor', cursorColor, defaultValue: null));
properties.add(DiagnosticsProperty<Brightness>('keyboardAppearance', keyboardAppearance, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('scrollPadding', scrollPadding, defaultValue: const EdgeInsets.all(20.0)));
@ -1248,7 +1253,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
TextSelectionControls? textSelectionControls = widget.selectionControls;
final bool paintCursorAboveText;
final bool cursorOpacityAnimates;
bool? cursorOpacityAnimates = widget.cursorOpacityAnimates;
Offset? cursorOffset;
final Color cursorColor;
final Color selectionColor;
@ -1262,7 +1267,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
forcePressEnabled = true;
textSelectionControls ??= cupertinoTextSelectionHandleControls;
paintCursorAboveText = true;
cursorOpacityAnimates = true;
cursorOpacityAnimates ??= true;
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? cupertinoTheme.primaryColor;
selectionColor = selectionStyle.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40);
cursorRadius ??= const Radius.circular(2.0);
@ -1274,7 +1279,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
forcePressEnabled = false;
textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls;
paintCursorAboveText = true;
cursorOpacityAnimates = false;
cursorOpacityAnimates ??= false;
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? cupertinoTheme.primaryColor;
selectionColor = selectionStyle.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40);
cursorRadius ??= const Radius.circular(2.0);
@ -1291,7 +1296,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
forcePressEnabled = false;
textSelectionControls ??= materialTextSelectionHandleControls;
paintCursorAboveText = false;
cursorOpacityAnimates = false;
cursorOpacityAnimates ??= false;
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
@ -1299,7 +1304,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
forcePressEnabled = false;
textSelectionControls ??= desktopTextSelectionHandleControls;
paintCursorAboveText = false;
cursorOpacityAnimates = false;
cursorOpacityAnimates ??= false;
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
@ -1307,7 +1312,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
forcePressEnabled = false;
textSelectionControls ??= desktopTextSelectionHandleControls;
paintCursorAboveText = false;
cursorOpacityAnimates = false;
cursorOpacityAnimates ??= false;
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
handleDidGainAccessibilityFocus = () {

View file

@ -1487,11 +1487,13 @@ class EditableText extends StatefulWidget {
/// {@endtemplate}
final Radius? cursorRadius;
/// {@template flutter.widgets.editableText.cursorOpacityAnimates}
/// Whether the cursor will animate from fully transparent to fully opaque
/// during each cursor blink.
///
/// By default, the cursor opacity will animate on iOS platforms and will not
/// animate on Android platforms.
/// {@endtemplate}
final bool cursorOpacityAnimates;
///{@macro flutter.rendering.RenderEditable.cursorOffset}

View file

@ -381,6 +381,31 @@ void main() {
},
);
testWidgets('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async {
// True
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(autofocus: true),
),
);
await tester.pump();
EditableText editableText = tester.widget(find.byType(EditableText));
expect(editableText.cursorOpacityAnimates, true);
// False
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(autofocus: true, cursorOpacityAnimates: false),
),
);
await tester.pump();
editableText = tester.widget(find.byType(EditableText));
expect(editableText.cursorOpacityAnimates, false);
});
testWidgets(
'takes available space horizontally and takes intrinsic space vertically',
(WidgetTester tester) async {

View file

@ -571,6 +571,35 @@ void main() {
expect(state.widget.cursorColor, cursorColor);
});
testWidgets('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async {
// True
await tester.pumpWidget(
const MaterialApp(
home: Material(
child: TextField(autofocus: true, cursorOpacityAnimates: true),
),
),
);
await tester.pump();
EditableText editableText = tester.widget(find.byType(EditableText));
expect(editableText.cursorOpacityAnimates, true);
// False
await tester.pumpWidget(
const MaterialApp(
home: Material(
child: TextField(autofocus: true, cursorOpacityAnimates: false),
),
),
);
await tester.pump();
editableText = tester.widget(find.byType(EditableText));
expect(editableText.cursorOpacityAnimates, false);
});
testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;