mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
fix(ios): correctly inherits the handle color from the theme (#166507)
## Description If specified, apply the `selectionHandleColor` from the theme to the iOS handle. ## Related Issue - https://github.com/flutter/flutter/issues/166506 #### Minimum reproducible example ```dart import 'package:flutter/material.dart'; void main() { runApp( MaterialApp( theme: ThemeData( textSelectionTheme: TextSelectionThemeData( selectionHandleColor: Colors.yellow, ), ), home: Scaffold(body: Center(child: TextField())), ), ); } ``` #### Visual Reference | Previous | Now | |--------|--------| | <img src="https://github.com/user-attachments/assets/91e49e07-ef4a-47ab-b65a-b147f441f252" /> | <img src="https://github.com/user-attachments/assets/fd27d602-6f7c-4d7d-a310-97f417bde819" /> | ## 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]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
This commit is contained in:
parent
761566b5d8
commit
a152df8357
1
AUTHORS
1
AUTHORS
@ -134,3 +134,4 @@ Mohammed Chahboun <m97.chahboun@gmail.com>
|
||||
Abdessalem Mohellebi <mohellebiabdessalem@gmail.com>
|
||||
Jin Jeongsu <jinjs.dev@gmail.com>
|
||||
Mairon Slusarz <maironlucaslusarz@gmail.com>
|
||||
Ricardo Dalarme <ricardodalarme@outlook.com>
|
||||
|
@ -122,7 +122,9 @@ class CupertinoTextSelectionControls extends TextSelectionControls {
|
||||
final Widget handle;
|
||||
|
||||
final Widget customPaint = CustomPaint(
|
||||
painter: _CupertinoTextSelectionHandlePainter(CupertinoTheme.of(context).primaryColor),
|
||||
painter: _CupertinoTextSelectionHandlePainter(
|
||||
CupertinoTheme.of(context).selectionHandleColor,
|
||||
),
|
||||
);
|
||||
|
||||
// [buildHandle]'s widget is positioned at the selection cursor's bottom
|
||||
|
@ -29,6 +29,7 @@ const _CupertinoThemeDefaults _kDefaultTheme = _CupertinoThemeDefaults(
|
||||
// Values extracted from navigation bar. For toolbar or tabbar the dark color is 0xF0161616.
|
||||
),
|
||||
CupertinoColors.systemBackground,
|
||||
CupertinoColors.systemBlue,
|
||||
false,
|
||||
_CupertinoTextThemeDefaults(CupertinoColors.label, CupertinoColors.inactiveGray),
|
||||
);
|
||||
@ -179,6 +180,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
CupertinoTextThemeData? textTheme,
|
||||
Color? barBackgroundColor,
|
||||
Color? scaffoldBackgroundColor,
|
||||
Color? selectionHandleColor,
|
||||
bool? applyThemeToAll,
|
||||
}) : this.raw(
|
||||
brightness,
|
||||
@ -187,6 +189,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
textTheme,
|
||||
barBackgroundColor,
|
||||
scaffoldBackgroundColor,
|
||||
selectionHandleColor,
|
||||
applyThemeToAll,
|
||||
);
|
||||
|
||||
@ -202,6 +205,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
CupertinoTextThemeData? textTheme,
|
||||
Color? barBackgroundColor,
|
||||
Color? scaffoldBackgroundColor,
|
||||
Color? selectionHandleColor,
|
||||
bool? applyThemeToAll,
|
||||
) : this._rawWithDefaults(
|
||||
brightness,
|
||||
@ -210,6 +214,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
textTheme,
|
||||
barBackgroundColor,
|
||||
scaffoldBackgroundColor,
|
||||
selectionHandleColor,
|
||||
applyThemeToAll,
|
||||
_kDefaultTheme,
|
||||
);
|
||||
@ -221,6 +226,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
CupertinoTextThemeData? textTheme,
|
||||
Color? barBackgroundColor,
|
||||
Color? scaffoldBackgroundColor,
|
||||
Color? selectionHandleColor,
|
||||
bool? applyThemeToAll,
|
||||
this._defaults,
|
||||
) : super(
|
||||
@ -230,6 +236,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
textTheme: textTheme,
|
||||
barBackgroundColor: barBackgroundColor,
|
||||
scaffoldBackgroundColor: scaffoldBackgroundColor,
|
||||
selectionHandleColor: selectionHandleColor,
|
||||
applyThemeToAll: applyThemeToAll,
|
||||
);
|
||||
|
||||
@ -255,6 +262,9 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
Color get scaffoldBackgroundColor =>
|
||||
super.scaffoldBackgroundColor ?? _defaults.scaffoldBackgroundColor;
|
||||
|
||||
@override
|
||||
Color get selectionHandleColor => super.selectionHandleColor ?? _defaults.selectionHandleColor;
|
||||
|
||||
@override
|
||||
bool get applyThemeToAll => super.applyThemeToAll ?? _defaults.applyThemeToAll;
|
||||
|
||||
@ -267,6 +277,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
textTheme: super.textTheme,
|
||||
barBackgroundColor: super.barBackgroundColor,
|
||||
scaffoldBackgroundColor: super.scaffoldBackgroundColor,
|
||||
selectionHandleColor: super.selectionHandleColor,
|
||||
applyThemeToAll: super.applyThemeToAll,
|
||||
);
|
||||
}
|
||||
@ -282,6 +293,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
super.textTheme?.resolveFrom(context),
|
||||
convertColor(super.barBackgroundColor),
|
||||
convertColor(super.scaffoldBackgroundColor),
|
||||
convertColor(super.selectionHandleColor),
|
||||
applyThemeToAll,
|
||||
_defaults.resolveFrom(context, super.textTheme == null),
|
||||
);
|
||||
@ -295,6 +307,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
CupertinoTextThemeData? textTheme,
|
||||
Color? barBackgroundColor,
|
||||
Color? scaffoldBackgroundColor,
|
||||
Color? selectionHandleColor,
|
||||
bool? applyThemeToAll,
|
||||
}) {
|
||||
return CupertinoThemeData._rawWithDefaults(
|
||||
@ -304,6 +317,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
textTheme ?? super.textTheme,
|
||||
barBackgroundColor ?? super.barBackgroundColor,
|
||||
scaffoldBackgroundColor ?? super.scaffoldBackgroundColor,
|
||||
selectionHandleColor ?? super.selectionHandleColor,
|
||||
applyThemeToAll ?? super.applyThemeToAll,
|
||||
_defaults,
|
||||
);
|
||||
@ -342,6 +356,13 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
defaultValue: defaultData.scaffoldBackgroundColor,
|
||||
),
|
||||
);
|
||||
properties.add(
|
||||
createCupertinoColorProperty(
|
||||
'selectionHandleColor',
|
||||
selectionHandleColor,
|
||||
defaultValue: defaultData.selectionHandleColor,
|
||||
),
|
||||
);
|
||||
properties.add(
|
||||
DiagnosticsProperty<bool>(
|
||||
'applyThemeToAll',
|
||||
@ -367,6 +388,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
other.textTheme == textTheme &&
|
||||
other.barBackgroundColor == barBackgroundColor &&
|
||||
other.scaffoldBackgroundColor == scaffoldBackgroundColor &&
|
||||
other.selectionHandleColor == selectionHandleColor &&
|
||||
other.applyThemeToAll == applyThemeToAll;
|
||||
}
|
||||
|
||||
@ -378,6 +400,7 @@ class CupertinoThemeData extends NoDefaultCupertinoThemeData with Diagnosticable
|
||||
textTheme,
|
||||
barBackgroundColor,
|
||||
scaffoldBackgroundColor,
|
||||
selectionHandleColor,
|
||||
applyThemeToAll,
|
||||
);
|
||||
}
|
||||
@ -406,6 +429,7 @@ class NoDefaultCupertinoThemeData {
|
||||
this.textTheme,
|
||||
this.barBackgroundColor,
|
||||
this.scaffoldBackgroundColor,
|
||||
this.selectionHandleColor,
|
||||
this.applyThemeToAll,
|
||||
});
|
||||
|
||||
@ -474,6 +498,11 @@ class NoDefaultCupertinoThemeData {
|
||||
/// Defaults to [CupertinoColors.systemBackground].
|
||||
final Color? scaffoldBackgroundColor;
|
||||
|
||||
/// The color of the selection handles on the text field.
|
||||
///
|
||||
/// Defaults to [CupertinoColors.systemBlue].
|
||||
final Color? selectionHandleColor;
|
||||
|
||||
/// Flag to apply this theme to all descendant Cupertino widgets.
|
||||
///
|
||||
/// Certain Cupertino widgets previously didn't use theming, matching past
|
||||
@ -513,6 +542,7 @@ class NoDefaultCupertinoThemeData {
|
||||
textTheme: textTheme?.resolveFrom(context),
|
||||
barBackgroundColor: convertColor(barBackgroundColor),
|
||||
scaffoldBackgroundColor: convertColor(scaffoldBackgroundColor),
|
||||
selectionHandleColor: convertColor(selectionHandleColor),
|
||||
applyThemeToAll: applyThemeToAll,
|
||||
);
|
||||
}
|
||||
@ -530,6 +560,7 @@ class NoDefaultCupertinoThemeData {
|
||||
CupertinoTextThemeData? textTheme,
|
||||
Color? barBackgroundColor,
|
||||
Color? scaffoldBackgroundColor,
|
||||
Color? selectionHandleColor,
|
||||
bool? applyThemeToAll,
|
||||
}) {
|
||||
return NoDefaultCupertinoThemeData(
|
||||
@ -539,6 +570,7 @@ class NoDefaultCupertinoThemeData {
|
||||
textTheme: textTheme ?? this.textTheme,
|
||||
barBackgroundColor: barBackgroundColor ?? this.barBackgroundColor,
|
||||
scaffoldBackgroundColor: scaffoldBackgroundColor ?? this.scaffoldBackgroundColor,
|
||||
selectionHandleColor: selectionHandleColor ?? this.selectionHandleColor,
|
||||
applyThemeToAll: applyThemeToAll ?? this.applyThemeToAll,
|
||||
);
|
||||
}
|
||||
@ -581,6 +613,7 @@ class _CupertinoThemeDefaults {
|
||||
this.primaryContrastingColor,
|
||||
this.barBackgroundColor,
|
||||
this.scaffoldBackgroundColor,
|
||||
this.selectionHandleColor,
|
||||
this.applyThemeToAll,
|
||||
this.textThemeDefaults,
|
||||
);
|
||||
@ -590,6 +623,7 @@ class _CupertinoThemeDefaults {
|
||||
final Color primaryContrastingColor;
|
||||
final Color barBackgroundColor;
|
||||
final Color scaffoldBackgroundColor;
|
||||
final Color selectionHandleColor;
|
||||
final bool applyThemeToAll;
|
||||
final _CupertinoTextThemeDefaults textThemeDefaults;
|
||||
|
||||
@ -602,6 +636,7 @@ class _CupertinoThemeDefaults {
|
||||
convertColor(primaryContrastingColor),
|
||||
convertColor(barBackgroundColor),
|
||||
convertColor(scaffoldBackgroundColor),
|
||||
convertColor(selectionHandleColor),
|
||||
applyThemeToAll,
|
||||
resolveTextTheme ? textThemeDefaults.resolveFrom(context) : textThemeDefaults,
|
||||
);
|
||||
|
@ -53,8 +53,8 @@ class TextSelectionThemeData with Diagnosticable {
|
||||
///
|
||||
/// On iOS [TextField] and [SelectableText] cannot access [selectionHandleColor].
|
||||
/// To set the [selectionHandleColor] on iOS, you can change the
|
||||
/// [CupertinoThemeData.primaryColor] by wrapping the subtree containing
|
||||
/// your [TextField] or [SelectableText] with a [CupertinoTheme].
|
||||
/// [CupertinoThemeData.selectionHandleColor] by wrapping the subtree
|
||||
/// containing your [TextField] or [SelectableText] with a [CupertinoTheme].
|
||||
final Color? selectionHandleColor;
|
||||
|
||||
/// Creates a copy of this object with the given fields replaced with the
|
||||
|
@ -2925,6 +2925,8 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
|
||||
_cupertinoOverrideTheme.textTheme,
|
||||
_cupertinoOverrideTheme.barBackgroundColor,
|
||||
_cupertinoOverrideTheme.scaffoldBackgroundColor,
|
||||
_cupertinoOverrideTheme.selectionHandleColor ??
|
||||
_materialTheme.textSelectionTheme.selectionHandleColor,
|
||||
_cupertinoOverrideTheme.applyThemeToAll,
|
||||
);
|
||||
|
||||
@ -2964,6 +2966,7 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
|
||||
CupertinoTextThemeData? textTheme,
|
||||
Color? barBackgroundColor,
|
||||
Color? scaffoldBackgroundColor,
|
||||
Color? selectionHandleColor,
|
||||
bool? applyThemeToAll,
|
||||
}) {
|
||||
return MaterialBasedCupertinoThemeData._(
|
||||
@ -2975,6 +2978,7 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
|
||||
textTheme: textTheme,
|
||||
barBackgroundColor: barBackgroundColor,
|
||||
scaffoldBackgroundColor: scaffoldBackgroundColor,
|
||||
selectionHandleColor: selectionHandleColor,
|
||||
applyThemeToAll: applyThemeToAll,
|
||||
),
|
||||
);
|
||||
|
@ -674,10 +674,10 @@ void main() {
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: const CupertinoThemeData(primaryColor: Colors.red),
|
||||
theme: const CupertinoThemeData(selectionHandleColor: Colors.red),
|
||||
home: Center(
|
||||
child: CupertinoTheme(
|
||||
data: const CupertinoThemeData(primaryColor: expectedSelectionHandleColor),
|
||||
data: const CupertinoThemeData(selectionHandleColor: expectedSelectionHandleColor),
|
||||
child: CupertinoTextField(controller: controller),
|
||||
),
|
||||
),
|
||||
|
@ -149,11 +149,45 @@ void main() {
|
||||
});
|
||||
|
||||
group('cupertino handles', () {
|
||||
testWidgets('draws custom handle correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
RepaintBoundary(
|
||||
child: CupertinoTheme(
|
||||
data: const CupertinoThemeData(selectionHandleColor: Color(0xFF9C27B0)),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
color: CupertinoColors.white,
|
||||
height: 800,
|
||||
width: 800,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 250),
|
||||
child: FittedBox(
|
||||
child: cupertinoTextSelectionControls.buildHandle(
|
||||
context,
|
||||
TextSelectionHandleType.right,
|
||||
10.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
find.byType(RepaintBoundary),
|
||||
matchesGoldenFile('text_selection.handle.custom.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('draws transparent handle correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
RepaintBoundary(
|
||||
child: CupertinoTheme(
|
||||
data: const CupertinoThemeData(primaryColor: Color(0x550000AA)),
|
||||
data: const CupertinoThemeData(selectionHandleColor: Color(0x550000AA)),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
|
@ -193,6 +193,7 @@ void main() {
|
||||
'navActionTextStyle',
|
||||
'pickerTextStyle',
|
||||
'dateTimePickerTextStyle',
|
||||
'selectionHandleColor',
|
||||
}),
|
||||
isTrue,
|
||||
);
|
||||
@ -272,6 +273,7 @@ void main() {
|
||||
colorMatches(theme.primaryContrastingColor, CupertinoColors.white);
|
||||
colorMatches(theme.barBackgroundColor, barBackgroundColor);
|
||||
colorMatches(theme.scaffoldBackgroundColor, CupertinoColors.systemBackground);
|
||||
colorMatches(theme.selectionHandleColor, CupertinoColors.systemBlue);
|
||||
colorMatches(theme.textTheme.textStyle.color, CupertinoColors.label);
|
||||
colorMatches(theme.textTheme.actionTextStyle.color, primaryColor);
|
||||
colorMatches(theme.textTheme.tabLabelTextStyle.color, CupertinoColors.inactiveGray);
|
||||
|
Loading…
Reference in New Issue
Block a user