这是indexloc提供的服务,不要输入任何密码
Skip to content

BottomAppBar: Fix doubled layers of color and shadow #123294

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

Merged
merged 27 commits into from
Apr 11, 2023

Conversation

chrisbobbe
Copy link
Contributor

@chrisbobbe chrisbobbe commented Mar 22, 2023

Fixes #123283.
Fixes #122667.
Fixes #123064.

(EDITED for the current revision, following #123283 (comment).)

The BottomAppBar implementation uses both a Material and a PhysicalShape because it needs them both in order to support the "notch" for a FAB in Material 2.

In the current version of the Material 3 support, it ends up putting a color and shadow on both of these, so that there are two color layers and two shadows. This gives wrong results when the color is translucent: #122667, #123064.

Also in Material 3, it doesn't work right if you ask for a notch, because the Material paints through the notch: #123283. (The Material 3 spec doesn't allow for a notch in the bottom app bar, but we plan to support one anyway: #123283 (comment).)

So, fix these bugs by making the Material transparent (and without overlay or shadow, using MaterialType.transparency), like we do in Material 2.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • 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.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

It's now a bit easier to read complete pictures of the Material 3
behavior and of the Material 2 behavior.

Soon we'll remove the PhysicalShape widget from the Material 3 case
entirely -- its job isn't needed in Material 3 because the bottom
app bar's "notched" shape isn't part of the spec anymore:
  https://m3.material.io/components/bottom-app-bar/specs
Fixes flutter#123283.
Fixes flutter#122667.
Fixes flutter#123064.

The Material 3 spec removes the "notched" shape for bottom app bars
that was present Material 2:
  https://m3.material.io/components/bottom-app-bar/specs

So, remove the `PhysicalShape` widget that was providing that
notched shape, and throw if callers in Material 3 ask for a notch.
Callers expecting a notch with Material 3 will have been
disappointed since da7b832, when the `Material` widget (which
doesn't support a notch) started painting its background color
through any notch provided by the `PhysicalShape` widget. This is
issue flutter#123283.

As a bonus, this fixes some bugs observed in Material 3 that were
invited by BottomAppBar's two-layer implementation (the
`PhysicalShape` and the `Material`):

- flutter#122667, "BottomAppBar: Material 3 makes the color too opaque"
- flutter#123064, "BottomAppBar: Elevation effect (shadow) doubled in
  Material 3"
Done by removing the line in bottom_app_bar_template.dart then:

  dart dev/tools/gen_defaults/bin/gen_defaults.dart

and undoing some unrelated-looking changes that made in these files:

  packages/flutter/lib/src/material/bottom_sheet.dart
  packages/flutter/lib/src/material/search_anchor.dart
`Material.surfaceTintColor` is ignored in Material 2. From the doc:

https://github.com/flutter/flutter/blob/2ad6cd72c0/packages/flutter/lib/src/material/material.dart#L283
> If [ThemeData.useMaterial3] is false, then this property is not used.

It was added for Material 3 support in 6a66aa2.
…terial

We already pass these to the `PhysicalShape`; the transparent
Material doesn't need them too.

As noted in
  flutter#123064 (comment)
, I don't think this redundancy in the Material 2 case has actually
caused a bug where an elevation effect gets doubled, because:
- A `Material` with `type: MaterialType.transparency` doesn't
  display a shadow:
    https://github.com/flutter/flutter/blob/f4c3facfd/packages/flutter/lib/src/material/material.dart#L522-L529
- `BottomAppBar` tries to apply an elevation overlay effect using
  `color` (with `ElevationOverlay.applyOverlay`), but `color` gets
  ignored by `Material` if `type` is `MaterialType.transparency`:
    https://github.com/flutter/flutter/blob/f4c3facfd/packages/flutter/lib/src/material/material.dart#L522-L529

Still, that's not trivial to verify, and it's more confusing to
keep passing these arguments.

(Note that this addresses the Material 2 case. In a recent commit,
we removed the `PhysicalShape` in the Material 3 case, fixing some
live bugs where some effects had in fact been duplicated by the
presence of the `PhysicalShape` together with the `Material`.)
@flutter-dashboard flutter-dashboard bot added f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. c: contributor-productivity Team-specific productivity, code health, technical debt. labels Mar 22, 2023
Comment on lines 228 to 237
child = PhysicalShape(
clipper: clipper,
elevation: elevation,
shadowColor: shadowColor,
color: ElevationOverlay.applyOverlay(context, color, elevation),
clipBehavior: widget.clipBehavior,
child: Material(
key: materialKey,
type: MaterialType.transparency,
child: SafeArea(child: child),
Copy link
Contributor Author

@chrisbobbe chrisbobbe Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, for the Material 2 case, is exactly like how this code was before Material 3 support was first added in #106525, except for the customizations added for padding in #115175 and for shadow color in #121406.

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix! Generally this looks good.

@@ -174,6 +189,8 @@ class _BottomAppBarState extends State<BottomAppBar> {
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final bool isMaterial3 = theme.useMaterial3;
assert(!isMaterial3 || widget.shape == null); // `shape` not accepted in Material 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The information in the comment should go in an assertion message instead, so the developer sees it when they hit the assertion. For example:

Suggested change
assert(!isMaterial3 || widget.shape == null); // `shape` not accepted in Material 3
assert(!isMaterial3 || widget.shape == null,
'The [BottomAppBar.shape] field is not permitted in Material 3.');

(Could also throw a FlutterError for a fancier error message, but this might be enough.)

Copy link
Contributor Author

@chrisbobbe chrisbobbe Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If throwing a FlutterError, would we want to do that in production too? AIUI asserts only throw in debug mode.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the check and the throw would both go inside an assert. For example, here's [State.context]:

  BuildContext get context {
    assert(() {
      if (_element == null) {
        throw FlutterError(
          'This widget has been unmounted, so the State no longer has a context (and should be considered defunct). \n'
          'Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.',
        );
      }
      return true;
    }());
    return _element!;
  }

@chrisbobbe
Copy link
Contributor Author

Thanks for the review, @gnprice! Changes pushed; PTAL. 🙂

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! One nit.

@chrisbobbe
Copy link
Contributor Author

chrisbobbe commented Mar 22, 2023

Thanks for the review! Fix pushed.

@chrisbobbe
Copy link
Contributor Author

I'm reworking this following @HansMuller's comment at #123283 (comment):

[T]he notch should still work with useMaterial3: true.

@flutter-dashboard
Copy link

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@justinmc
Copy link
Contributor

justinmc commented Mar 23, 2023

Sounds good, I'm happy to give a secondary review when this is back out of draft mode.

Edit: By the way, the Google testing failures look like there's a small pixel difference at the right edge of the BottomAppBar in some image diff tests. Likely it's intended, but I'll take another look after the PR is updated.

@chrisbobbe
Copy link
Contributor Author

Thanks for the review!

(I think a merge would probably also do it.)

Done.

@gnprice
Copy link
Member

gnprice commented Mar 24, 2023

Google testing failed. This is likely the same failures @justinmc mentioned above:

By the way, the Google testing failures look like there's a small pixel difference at the right edge of the BottomAppBar in some image diff tests. Likely it's intended, but I'll take another look after the PR is updated.

Customer testing also failed, in a way unrelated to this PR: #123385

@justinmc
Copy link
Contributor

@chrisbobbe Can you merge master into this PR? That will fix the customer tests and update the Google tests so I can take a look.

@chrisbobbe
Copy link
Contributor Author

Sure! Done.

@justinmc
Copy link
Contributor

Thanks, looks like the customer tests are fixed. I'll check on the Google tests next week.

@justinmc
Copy link
Contributor

justinmc commented Apr 3, 2023

The Google test failure looks unrelated... Can you try pushing another merge commit? Sorry for all the headache with this.

@chrisbobbe
Copy link
Contributor Author

Sure, no problem! Done.

@chrisbobbe
Copy link
Contributor Author

Hmm, Google testing is still showing as "pending" after 7+ hours. Could be #123289?

This time I'm going to try and see if I can update the branch without leaving GitHub's UI. There's a helpful-looking "Update branch" button that I'm going to click now. (If that does something wrong, I can always reset the branch back to b084982, my merge commit from earlier today.)

@HansMuller
Copy link
Contributor

@XilaiZhang - apparently this PR has failed "Google Testng" however the details link doesn't reveal anything: "There is no unmerged PR.". I tried the "Test a PR" button to start another test and that failed with:

Screenshot 2023-04-04 at 8 47 48 AM

How can we move the process along?

@XilaiZhang
Copy link
Contributor

temp workaround: the test failures are at test/521647510 and the cl is cl/521647510

Thanks for reporting the issue! will keep track of it in b/260764527

@HansMuller
Copy link
Contributor

The Google testing failures don't appear to have anything to do with this PR. Will try updating the branch...

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

I think that Google testing is broken right now, so we'll have to try pushing another merge commit in a day or so when it's fixed.

@@ -33,7 +33,8 @@ import 'theme.dart';
/// {@end-tool}
///
/// {@tool dartpad}
/// This example shows the [BottomAppBar], which can be configured to have a notch using the
/// This example shows the [BottomAppBar], which (in Material 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in #123283 (comment) we ideally want to keep the ability to have a notch with useMaterial3: true. I'm guessing but I imagine there will be a significant amount of people that want a Material 3-looking app with a notch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is already addressed in this revision (I suspect your review-draft crossed with my sending that new revision). I've updated the PR description to match this revision. 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, yeah this review was messed up somehow...

@@ -218,19 +284,18 @@ void main() {
),
bottomNavigationBar: BottomAppBar(
color: Color(0xff0000ff),
surfaceTintColor: Colors.transparent,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you file a new issue about the docs being wrong?

@chrisbobbe
Copy link
Contributor Author

Thanks for the review!

I think that Google testing is broken right now, so we'll have to try pushing another merge commit in a day or so when it's fixed.

Sure, I'll try that now.

@justinmc
Copy link
Contributor

Thanks for pushing the merge commit. It looks like there are real Google test failures, but they are just nearly invisible image diffs due to the changes here. I've accepted the changes and should be able to merge this soon.

@justinmc justinmc merged commit 952ace6 into flutter:master Apr 11, 2023
@gnprice
Copy link
Member

gnprice commented Apr 11, 2023

Thanks @justinmc and everyone for your help in taking care of Google testing!

@chrisbobbe chrisbobbe deleted the pr-bottom-app-bar-notch-material-3 branch April 11, 2023 20:36
@chrisbobbe
Copy link
Contributor Author

Yeah, thanks all! 🎉

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 12, 2023
exaby73 pushed a commit to exaby73/flutter_nevercode that referenced this pull request Apr 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: contributor-productivity Team-specific productivity, code health, technical debt. f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
5 participants