flutter
flutter copied to clipboard
Date picker overlay colors aren't applied on `MaterialState.selected` state.
Is there an existing issue for this?
- [X] I have searched the existing issues
- [X] I have read the guide to filing a bug
Steps to reproduce
Apply selected overlay color in DatePickerTheme.dayOverlayColor and DatePickerTheme.yearOverlayColor
if (states.contains(MaterialState.selected)) {
return Colors.green;
}
Expected results
Actual results
Code sample
Code sample
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
datePickerTheme: DatePickerThemeData(
yearOverlayColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
print('yearOverlayColor.states: $states');
if (states.contains(MaterialState.selected)) {
return Colors.green;
}
return Colors.transparent;
}),
dayOverlayColor:
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
print('dayOverlayColor.states: $states');
if (states.contains(MaterialState.selected)) {
return Colors.red;
}
return Colors.transparent;
}),
),
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: DatePickerDialog(
initialDate: DateTime(2023, DateTime.january, 25),
firstDate: DateTime(2022),
lastDate: DateTime(2024, DateTime.december, 31),
currentDate: DateTime(2023, DateTime.january, 24),
),
),
),
),
);
}
}
Screenshots or Video
Screenshots / Video demonstration
[Upload media here]
Logs
Logs
[Paste your logs here]
Flutter Doctor output
Doctor output
[!] Flutter (Channel [user-branch], 3.13.0-3.0.pre.64, on macOS 13.4.1 22F82 darwin-arm64, locale en-EE)
! Flutter version 3.13.0-3.0.pre.64 on channel [user-branch] at /Users/tahatesser/Code/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions at
https://flutter.dev/docs/get-started/install.
! Upstream repository [email protected]:TahaTesser/flutter.git is not the same as FLUTTER_GIT_URL
• FLUTTER_GIT_URL = [email protected]:NevercodeHQ/flutter.git
• Framework revision 418d6a56f9 (5 hours ago), 2023-07-14 13:59:16 +0300
• Engine revision 3a1b12a2fa
• Dart version 3.1.0 (build 3.1.0-310.0.dev)
• DevTools version 2.25.0
• If those were intentional, you can disregard the above warnings; however it is recommended to use
"git" directly to perform update checks and upgrades.
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/tahatesser/Code/android-sdk
• Platform android-34, build-tools 34.0.0
• ANDROID_SDK_ROOT = /Users/tahatesser/Code/android-sdk
• Java binary at: /Applications/Android Studio Preview.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b829.16-10353782)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
• Xcode at /Applications/Xcode-14.3.1.app/Contents/Developer
• Build 14E300c
• CocoaPods version 1.12.1
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[!] Android Studio (version unknown)
• Android Studio at /Applications/Android Studio Preview.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
✗ Unable to determine Android Studio version.
• Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b829.16-10353782)
[✓] VS Code (version 1.80.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.68.0
[✓] Connected device (2 available)
• macOS (desktop) • macos • darwin-arm64 • macOS 13.4.1 22F82 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.198
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 2 categories.
cc: @rydmike Did you notice this issue? Am I correct to expect the selected overlay color here? I can see there is a selected state but color isn't picked up.
Hover, Focus, & Press work just for fine but internal inkwell uses MaterialStateController for passing selected state which doesn't work to overlay color.
I noticed this issue while writing a bunch of overlay tests for https://github.com/flutter/flutter/issues/130051
Thanks for the report, @TahaTesser
I can see the issue if the check condition compares to MaterialState.selected, noticed below output log and black overlay color.
flutter: dayOverlayColor.states: {MaterialState.selected, MaterialState.hovered}
flutter: dayOverlayColor.states: {MaterialState.hovered}
But it seems to work if I change the check condition compares to MaterialState.hovered. The same states are logged but can see the expected result (green overlay color when hovering and pressing). I am not sure about the output state here. Looks like this is a MaterialState issue? Or is using MaterialState.hovered applicable for this case?
Other states work because Inkwell automatically handles but the selected state is provided via MaterialStateController.
Looks like this is a MaterialState issue?
It seems to be related to MaterialStateController. I can produce with just InkWell with MaterialStateController for the selected state.
I think other widgets which also use MaterialStateController to provide a selected state might reproduce this issue.
Code sample
expand to view the code sample
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late MaterialStatesController _controller;
@override
void initState() {
super.initState();
_controller =
MaterialStatesController(<MaterialState>{MaterialState.selected});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final MaterialStateProperty<Color> overlayColor =
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
print('states: $states');
if (states.contains(MaterialState.selected)) {
return Colors.green;
}
return Colors.transparent;
});
return MaterialApp(
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: InkWell(
statesController: _controller,
overlayColor: overlayColor,
onTap: () {},
child: Container(
decoration: BoxDecoration(border: Border.all()),
width: 100,
height: 100,
),
),
),
),
),
);
}
}
futter: states: {MaterialState.selected, MaterialState.hovered}
flutter: states: {MaterialState.hovered}
Since InkWell fires MaterialState.selected, MaterialState.hovered then only MaterialState.hovered before the color is drawn so the selected state is never picked up for the color to be drawn.
Thanks for the update.
Regarding hovered state with mouse interaction, I see this in M3 specs:
Hover states can be combined with focused, activated, selected, or pressed states.
Also with focused state when using Tab key to focus on widget:
Focus states can be represented in combination with hover, activated, or selected states.
flutter: states: {MaterialState.selected, MaterialState.focused}
flutter: states: {MaterialState.focused}
But I don't see any M3 specs mention to state order. It's quite more detailed on M2 specs, though. In Flutter, it seems the overlay color is only drawn by the latest state (hovered), ignoring intermediate states (selected). This corresponds to the original issue. Let's check below sample code with timeDilation = 20.0:
final MaterialStateProperty<Color> overlayColor = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
print('states: $states');
if (states.contains(MaterialState.selected)) {
return Colors.green;
}
if (states.contains(MaterialState.hovered)) {
return Colors.red;
}
return Colors.transparent;
});
Demo video (timeDilation = 20.0)
https://github.com/flutter/flutter/assets/104349824/c858bd18-42ac-4982-8c62-251b620bec2a
Reproduced this issue on latest stable and master channels.
flutter doctor -v (stable and master)
[✓] Flutter (Channel stable, 3.10.6, on macOS 13.0.1 22A400 darwin-x64, locale en-VN)
• Flutter version 3.10.6 on channel stable at /Users/huynq/Documents/GitHub/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision f468f3366c (5 hours ago), 2023-07-12 15:19:05 -0700
• Engine revision cdbeda788a
• Dart version 3.0.6
• DevTools version 2.23.1
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
• Android SDK at /Users/huynq/Library/Android/sdk
• Platform android-33, build-tools 32.0.0
• ANDROID_HOME = /Users/huynq/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 14E222b
• CocoaPods version 1.11.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2022.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
[✓] VS Code (version 1.80.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.68.0
[✓] Connected device (3 available)
• RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64 • Android 11 (API 30)
• macOS (desktop) • macos • darwin-x64 • macOS 13.0.1 22A400 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.198
[✓] Network resources
• All expected network resources are available.
• No issues found!
[!] Flutter (Channel master, 3.13.0-5.0.pre.34, on macOS 13.0.1 22A400 darwin-x64, locale en-VN)
• Flutter version 3.13.0-5.0.pre.34 on channel master at /Users/huynq/Documents/GitHub/flutter_master
! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 8a8f023466 (26 minutes ago), 2023-07-17 22:46:27 -0400
• Engine revision f2958f9229
• Dart version 3.1.0 (build 3.1.0-320.0.dev)
• DevTools version 2.25.0
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
• Android SDK at /Users/huynq/Library/Android/sdk
• Platform android-33, build-tools 32.0.0
• ANDROID_HOME = /Users/huynq/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 14E222b
• CocoaPods version 1.11.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2022.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
[✓] VS Code (version 1.80.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.68.0
[✓] Connected device (4 available)
• RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64 • Android 11 (API 30)
• iPhone (mobile) • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios • iOS 15.7.2 19H218
• macOS (desktop) • macos • darwin-x64 • macOS 13.0.1 22A400 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.198
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.
This is reproducible in buttons as well.
It looks like the last state reported isn't selected
flutter: selected
flutter: no state
Code sample
expand to view the code sample
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(useMaterial3: true),
home: const Example(),
);
}
}
class Example extends StatefulWidget {
const Example({super.key});
@override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
late MaterialStatesController statesController;
@override
void initState() {
super.initState();
statesController =
MaterialStatesController(<MaterialState>{MaterialState.selected});
}
@override
void dispose() {
statesController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final MaterialStateProperty<Color?> overlayColor =
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
print('selected');
return Colors.blue;
}
print('no state');
return Colors.transparent;
});
return Scaffold(
appBar: AppBar(
title: const Text('Sample'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
TextButton(
statesController: statesController,
style: ButtonStyle(
overlayColor: overlayColor,
),
onPressed: () {},
child: const Text('TextButton'),
),
InkWell(
statesController: statesController,
overlayColor: overlayColor,
onTap: () {},
child: Container(
decoration: BoxDecoration(border: Border.all()),
width: 100,
height: 100,
),
)
],
),
),
);
}
}
cc: @bleroux If you've any insight or fix for this.
Similarly IconButton has an internal MaterialStatesController and it also doesn't return the color in the selected state.
final MaterialStateProperty<Color?> overlayColor =
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
print('selected');
return Colors.blue;
}
print('no state');
return Colors.transparent;
});
IconButton(
style: ButtonStyle(
overlayColor: overlayColor,
),
onPressed: () {},
isSelected: true,
icon: const Icon(Icons.abc),
),
This issue is assigned to @HansMuller but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!
dayBackgroundColor: MaterialStateColor.resolveWith(
(Set<MaterialState> states) {
Color? color;
if (states.contains(MaterialState.selected)) {
color = Colors.green;
}
return color ?? Colors.transparent;
},
),