Thanks to visit codestin.com
Credit goes to github.com

Skip to content

MaterialStateColor.resolveWith cannot return null value. #116590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TahaTesser opened this issue Dec 6, 2022 · 4 comments
Closed

MaterialStateColor.resolveWith cannot return null value. #116590

TahaTesser opened this issue Dec 6, 2022 · 4 comments
Labels
f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Comments

@TahaTesser
Copy link
Member

TahaTesser commented Dec 6, 2022

I've come across this in previous PRs and in a recent PR.

Take this as an example where Color? get selectedColor is nullable but MaterialStateColor.resolveWith doesn't allow returning a null value.

In a case where we need to return a null so an "effectiveColor" variable can fall back to a different color for the default property.

  @override
  Color? get selectedColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
    if (states.contains(MaterialState.selected)) {
      return _themeData.colorScheme.primary;
    }
    
    // cannot return a null.
    return null;
  });

I would have to provide a condition to avoid getting Colors.transparent, like this.

  @override
  Color? get selectedColor =>  _themeData.colorScheme.primary;
   /// ....
    final Color? effectiveSelectedColor = MaterialStateProperty.resolveAs<Color?>(selectedColor, states)
      ?? MaterialStateProperty.resolveAs<Color?>(tileTheme.selectedColor, states)
      ?? MaterialStateProperty.resolveAs<Color?>(theme.listTileTheme.selectedColor, states)
      ?? (states.contains(MaterialState.selected) ? defaults.selectedColor : null);

I've noticed this pattern throughout the framework where MaterialStateColor.resolveWith often resorts to Colors.transparent. I would like to make sure this doesn't go unnoticed if it is by design and if there is a way to return null.

Here are some instances:

if (states.contains(MaterialState.hovered)) {
return _colors.onSurface.withOpacity(0.08);
}
if (states.contains(MaterialState.focused)) {
return _colors.onSurface.withOpacity(0.12);
}
return Colors.transparent;
},

}
return Colors.transparent;
}
if (states.contains(MaterialState.pressed)) {
return _colors.primary.withOpacity(0.12);
}
if (states.contains(MaterialState.hovered)) {
return _colors.onSurface.withOpacity(0.08);
}
if (states.contains(MaterialState.focused)) {
return _colors.onSurface.withOpacity(0.12);
}
return Colors.transparent;

Color? get overlayColor => MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return _colors.primary.withOpacity(0.08);
}
if (states.contains(MaterialState.focused)) {
return _colors.primary.withOpacity(0.12);
}
if (states.contains(MaterialState.dragged)) {
return _colors.primary.withOpacity(0.12);
}
return Colors.transparent;
});

@TahaTesser TahaTesser added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Dec 6, 2022
@TahaTesser
Copy link
Member Author

cc: @HansMuller

@TahaTesser TahaTesser changed the title MaterialStateColor.resolveWith cannot return null value even when property is nullable. MaterialStateColor.resolveWith cannot return null value. Dec 6, 2022
@HansMuller
Copy link
Contributor

HansMuller commented Dec 6, 2022

I think you mean that MaterialStateColor.resolve can't return null. On the face of it, that does seem like a mistake, however fixing it would be a breaking change.

Sorry, that's wrong. A MaterialStateColor is-a Color, so its resolve method can't return null. But MaterialStateProperty.resolveAs<Color?> does the right thing if its value parameter is null.

I believe that the places where we're returning Colors.transparent by default are intentional, to distinguish a situation where no fill color is desired vs "use the default fill color".

CC @darrenaustin

@darrenaustin
Copy link
Contributor

Yeah the main use of transparent was to indicate that you didn't want a color for something that had a default. Trying to use null for that case doesn't work, as it is used to indicate that you want the default, not that you don't want any color. The main example of this is with shadowColor and surfaceTintColor.

As for the issue at hand here, as Hans pointed out, it wouldn't make sense for MaterialStateColor.resolve to be able to return null as its type is MaterialStateProperty<Color> not MaterialStateProperty<Color?>. I'm going to close this as working as designed.

@github-actions
Copy link

github-actions bot commented Mar 5, 2023

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

No branches or pull requests

3 participants