Repository navigation
Fix TabBar assertion to allow indicatorWeight: 0 with a themed indicator - #189157
Massinissa-Mouhoub wants to merge 6 commits into
Conversation
TabBar assertion to allow indicatorWeight: 0 with a themed indicator
There was a problem hiding this comment.
Code Review
This pull request updates the TabBar and TabBar.secondary constructors by removing the assertion that requires indicatorWeight to be greater than 0.0 when a custom indicator is provided. Instead, the assertion is now deferred to the state build phase, where it is only triggered if the default underline indicator is drawn. New widget tests have been added to verify that indicatorWeight can be 0.0 when a custom indicator is supplied via the widget or TabBarThemeData, and that it still asserts when using the default indicator. There are no review comments, and I have no feedback to provide.
|
The
so there's no subset of the change I can split out to get the gate green. For context on what the change does: I read #184093 as saying PRs like this should stay open and then be ported to |
dkwingsmt
left a comment
There was a problem hiding this comment.
Can you also fix the doc for indicatorWeight, just like https://github.com/flutter/flutter/pull/188967/changes#diff-b90db0bc5b533dbd8ef4c5099057b292200e0aa96125e74ab3646c783b468bbdR1140 ? Here's my proposal:
/// If [indicator] is specified or provided from [TabBarThemeData],
/// this property is ignored. Otherwise, when drawing the default underline
/// indicator, the value of this parameter must be greater than zero.Otherwise LGTM.
| assert( | ||
| widget.indicatorWeight > 0.0, | ||
| 'The indicatorWeight must be greater than 0 when the TabBar ' | ||
| 'draws its default underline indicator (i.e. when no indicator is ' | ||
| 'provided by the TabBar or the TabBarTheme).', | ||
| ); |
There was a problem hiding this comment.
The detailed message is great! I wonder if the displayed error screen can be even more understandable if you throw a FlutterError.fromParts from within an assert, something like
assert(() {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('Invalid indicatorWeight for TabBar.'),
ErrorDescription('indicatorWeight must be greater than zero when using the default underline indicator.'),
ErrorHint('To fix this, set indicatorWeight > 0 or specify an indicator in TabBarTheme.'),
]);
return true;
}());Can you try?
There was a problem hiding this comment.
I tried your approach with a small modification:
assert(() {
if (widget.indicatorWeight <= 0.0) { // This was added to prevent throwing unconditionaly
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('Invalid indicatorWeight for TabBar.'),
ErrorDescription(
'The indicatorWeight must be greater than zero when the TabBar '
'draws its default underline indicator, that is when no indicator '
'is provided by the TabBar or the TabBarTheme.',
),
ErrorHint(
'To fix this, set indicatorWeight to a value greater than zero, '
'or provide an indicator with the TabBar.indicator or '
'TabBarThemeData.indicator property.',
),
]);
}
return true;
}());Below is the displayed error on-screen before and after:
| Before | After |
|---|---|
![]() |
![]() |
Below is the error on console:
Before
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building MediaQuery(MediaQueryData(size: Size(440.0, 956.0), devicePixelRatio: 3.0, textScaler: SystemTextScaler (no scaling), platformBrightness: Brightness.light, padding: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, systemGestureInsets: EdgeInsets.zero, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast: false, onOffSwitchLabels: false, disableAnimations: false, invertColors: false, boldText: false, navigationMode: traditional, gestureSettings: DeviceGestureSettings(touchSlop: null), displayFeatures: [], supportsShowingSystemContextMenu: true, lineHeightScaleFactorOverride: null, letterSpacingOverride: null, wordSpacingOverride: null, paragraphSpacingOverride: null, displayCornerRadii: null)):
The indicatorWeight must be greater than 0 when the TabBar draws its default underline indicator (i.e. when no indicator is provided by the TabBar or the TabBarTheme).
'package:flutter/src/material/tabs.dart':
Failed assertion: line 1595 pos 7: 'widget.indicatorWeight > 0.0'
After
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building MediaQuery(MediaQueryData(size: Size(440.0, 956.0), devicePixelRatio: 3.0, textScaler: SystemTextScaler (no scaling), platformBrightness: Brightness.light, padding: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, systemGestureInsets: EdgeInsets.zero, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast: false, onOffSwitchLabels: false, disableAnimations: false, invertColors: false, boldText: false, navigationMode: traditional, gestureSettings: DeviceGestureSettings(touchSlop: null), displayFeatures: [], supportsShowingSystemContextMenu: true, lineHeightScaleFactorOverride: null, letterSpacingOverride: null, wordSpacingOverride: null, paragraphSpacingOverride: null, displayCornerRadii: null)):
Invalid indicatorWeight for TabBar.
The indicatorWeight must be greater than zero when the TabBar draws its default underline indicator, that is when no indicator is provided by the TabBar or the TabBarTheme.
To fix this, set indicatorWeight to a value greater than zero, or provide an indicator with the TabBar.indicator or TabBarThemeData.indicator property.
I don't see an improvement on the displayed error, but I largly prefer the console error after the fix. I think it's better if we go with this new approach.
|
dkwingsmt Please check the latest commit, I updated the docs and applied your suggestion for throwing the assertion. |
QuncCccccc
left a comment
There was a problem hiding this comment.
Thanks for your contribution! The code fix looks great. Just left some comments in tests.
|
@QuncCccccc I applied your comments, please check. |
QuncCccccc
left a comment
There was a problem hiding this comment.
LGTM! Thanks a lot for your contribution:)
|
@QuncCccccc, could you please add autosubmit to this PR since it's been approved? |
|
@Massinissa-Mouhoub Since this PR affects |
Alright perfect, thank you! |
|
There's a leakage failure: |
…indicator Covers flutter#188837: - themed indicator (TabBarThemeData.indicator) + indicatorWeight: 0 no longer asserts and renders the themed indicator (primary and secondary); - widget-level indicator + indicatorWeight: 0 does not assert; - default underline indicator + indicatorWeight: 0 still asserts.
…rWeight Per review feedback, replace the plain assert message with a FlutterError.fromParts thrown from within an assert, so the debug-mode error screen shows a structured summary, description, and fix hint. Also update the TabBar.indicatorWeight API documentation to state that the value must be greater than zero when the default underline indicator is used, and update the regression test to match the new FlutterError.
5731712
022891d to
5731712
Compare
|
@dkwingsmt can you please check? It's my first time dealing with leakage, so I'm not really sure of the way I solved it. |
|
@dkwingsmt can you take a look at this when you are free please ? |
|
Thanks for your contribution! This PR has reached completion, however we're not able to merge this PR for the moment due to the Material/Cupertino code freeze (#184093). As soon as the decoupling is complete, we will post a way to port this PR to the new packages to land. In the meantime, I'll convert this PR to a draft and apply a label so that we can quickly find it when the freeze is lifted. |
ceff3ed
|
@dkwingsmt Alright thank you! I applied your comment suggestion in the last commit. |
|
@dkwingsmt @QuncCccccc this PR was ported in this PR please check it there. |
|
Since we have a port PR for this fix, I'm closing this PR. Thanks a lot for porting it over! |
…th a themed `indicator` (#12696) This is the port of this [PR](flutter/flutter#189157) after decoupling. Fixes flutter/flutter#188837. ## Original PR Description This PR moves the assertion that checks indicator != null || (indicatorWeight > 0.0) from the TabBar constructors into the Decoration _getIndicator(TabBarIndicatorSize indicatorSize) method. During the first phase of creating the TabBar widget, Dart just fills in the fields, there is no BuildContext available yet, so the widget has no way of access the TabBarTheme via context.dependOnInheritedWidgetOfExactType<TabBarTheme>(). As a result, the constructor's assertion can only see the indicator passed directly to the widget, and it fails even when a valid indicator is supplied through the TabBarTheme. By moving the assertion into the method mentionned above, which runs at build time, the TabBar now has access to the TabBarTheme and can validate the indicator correctly, accepting indicatorWeight: 0 when a themed indicator is present, while still asserting when the default underline indicator is used. Fixes flutter/flutter#188837 ## Pre-Review Checklist


This PR moves the assertion that checks
indicator != null || (indicatorWeight > 0.0)from theTabBarconstructors into theDecoration _getIndicator(TabBarIndicatorSize indicatorSize)method. During the first phase of creating theTabBarwidget, Dart just fills in the fields, there is noBuildContextavailable yet, so the widget has no way of access theTabBarThemeviacontext.dependOnInheritedWidgetOfExactType<TabBarTheme>(). As a result, the constructor's assertion can only see theindicatorpassed directly to the widget, and it fails even when a valid indicator is supplied through theTabBarTheme.By moving the assertion into the method mentionned above, which runs at build time, the
TabBarnow has access to theTabBarThemeand can validate theindicatorcorrectly, acceptingindicatorWeight: 0when a themed indicator is present, while still asserting when the default underline indicator is used.Fixes #188837
Pre-launch Checklist
///).