-
Notifications
You must be signed in to change notification settings - Fork 28.7k
Make TabBar indicator color automatic adjustment optional #68171
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think adding the parameter is fine for a workaround, although a longer term solution is probably warranted. I think it's weird that we try to "be too helpful" here and default to Colors.white
when the colors are the same.
But, as you said, it's a breaking change and maybe the right thing to do if it's not too breaking is to just remove the Colors.white
code and the automaticIndicatorColorAdjustment
parameter, but we'll need to look into how prevalent this actually is.
/// | ||
/// If [automaticIndicatorColorAdjustment] is true, | ||
/// then the [indicatorColor] will be automatically adjusted to [Colors.white] | ||
/// when the [indicatorColor] is same as [Material.color]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth being specific about which Material.color
you're referencing here:
/// when the [indicatorColor] is same as [Material.color]. | |
/// when the [indicatorColor] is same as [Material.color] of the [Material] parent widget. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -345,7 +345,7 @@ class ThemeData with Diagnosticable { | |||
textSelectionHandleColor ??= isDark ? Colors.tealAccent[400]! : primarySwatch[300]!; | |||
backgroundColor ??= isDark ? Colors.grey[700]! : primarySwatch[200]!; | |||
dialogBackgroundColor ??= isDark ? Colors.grey[800]! : Colors.white; | |||
indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor; | |||
indicatorColor ??= accentColor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that you explained it in the PR description, but I don't quite understand what you mean since it's still possible for both accentColor and pimaryColor to be a Color
, which would cause the theme default indicator color to be Colors.white
. Any apps expecting this behavior would break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand what you mean.
Imagine such a situation, if the pimaryColor
is MaterialColor(primary value: Color(0xff2196f3))
or Color(0xff2196f3))
and the accentColor
is Color(0xff2196f3))
, Visually they are the same color but have different indicator colors. This behavior is very strange and incomprehensible. What I think is that if we haven't broken something now, we can fix it to avoid this weird behavior in the future.
Of course, this issue has nothing to do with this PR, I will open another topic to discuss this, thank you for your suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Track at #69162
testWidgets('Tab indicator color should not be adjusted when disable [automaticIndicatorColorAdjustment]', (WidgetTester tester) async { | ||
// Regression test for https://github.com/flutter/flutter/issues/68077 | ||
final List<String> tabs = <String>['LEFT', 'RIGHT']; | ||
await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT', automaticIndicatorColorAdjustment: false)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would also need to apply the indicatorColor
and Material.color
to be the same value in the test, since it's expected that otherwise, the color of the indicator is always the expected value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case is the situation that indicatorColor
equal Material.color
because automaticIndicatorColorAdjustment
is false and the color didn't adjust to white.
This is an opposite test of the above test Default tab indicator color is white
testWidgets('Default tab indicator color is white', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/15958
final List<String> tabs = <String>['LEFT', 'RIGHT'];
await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
expect(tabBarBox, paints..line(
color: Colors.white,
));
});
@@ -821,7 +829,9 @@ class _TabBarState extends State<TabBar> { | |||
// | |||
// The material's color might be null (if it's a transparency). In that case | |||
// there's no good way for us to find out what the color is so we don't. | |||
if (color.value == Material.of(context)?.color?.value) | |||
// TODO(xu-baolin): Remove this code without breaking something. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I add a TODO
here for the possible long-term solutions in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think adding a TODO
here is good, let's just make it a little more descriptive since we might never get back to it, but a future Flutter developer might. I'm thinking:
// TODO(xu-baolin): Remove automatic adjustment to white color indicator with a better long-term solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Just a note on improving clarification of the TODO
Might need a rebase -- unrelated |
I really don't know how to solve this problem, can I just turn off this PR and reopen one? +_+ |
According to the flutter discord channel, this should work:
However, if that doesn't work, feel free and just create a new branch and close this one out. This problem is a weird one, thanks for putting up with it! |
It actually works! Thanks very much ! |
Description
The automatic adjustment behavior of the tab bar indicator color is not documented in the API doc, I think we should document that.
flutter/packages/flutter/lib/src/material/tabs.dart
Lines 814 to 825 in ed2a480
At the same time, there are several reasons that let developers have the opportunity to not apply this behavior:
1、This automatic adjustment solution is not perfect as the discussion at #14741 (comment)
2、Sometimes developer wants the same color such as #68077
3、Even if they are the same color, it does not necessarily cause the indicator to be invisible such as #68077
In summary, considering backward compatibility, I set the
automaticIndicatorColorAdjustment
default value to true. Of course, I would love to hear that you have a better solution.flutter/packages/flutter/lib/src/material/theme_data.dart
Line 348 in ed2a480
I believe this should be a typo instead of
accentColor.value == primaryColor.value
.Most of the time,
primaryColor
isMaterialColor
type andaccentColor
isColor
type. They cannot be compared directly with==
, otherwise it will not be the expected result.Considering backward compatibility and do not want to break something, I make this change to avoid future undesired behaviors.
Related Issues
Fixes #68077
Tests
I added the following tests:
See files.