Open md-weber opened 10 months ago
Hi @md-weber. Thanks for filing this issue. I am able to reproduce this on the latest master
and stable
channels. The appBar
color changes/ appears & disappears without animation as shown in the documentation.
```dart
import 'package:flutter/material.dart';
/// Flutter code sample for [AppBar].
final List
https://github.com/flutter/flutter/assets/53122008/87710ccb-9be2-487d-b25f-264499195e0e
``` [✓] Flutter (Channel stable, 3.10.6, on macOS 13.0 22A380 darwin-arm64, locale en-NG) • Flutter version 3.10.6 on channel stable at /Users/damilolaalimi/sdks/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision f468f3366c (9 days 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 34.0.0) • Android SDK at /Users/damilolaalimi/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • 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.1) • Xcode at /Applications/Xcode.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 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.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.50.0 [✓] Connected device (4 available) • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 14 (API 34) (emulator) • iPhone 14 (mobile) • 1A122DE2-0CAB-4C3E-A395-691BF27D626F • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 13.0 22A380 darwin-arm64 • 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-7.0.pre.59, on macOS 13.0 22A380 darwin-arm64, locale en-NG) • Flutter version 3.13.0-7.0.pre.59 on channel master at /Users/damilolaalimi/fvm/versions/master • Upstream repository https://github.com/flutter/flutter.git • Framework revision f629809938 (4 hours ago), 2023-07-21 02:09:23 -0400 • Engine revision 264685f0ae • Dart version 3.1.0 (build 3.1.0-333.0.dev) • DevTools version 2.25.0 [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/damilolaalimi/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • 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.1) • Xcode at /Applications/Xcode.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 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.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.50.0 [✓] Connected device (4 available) • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 14 (API 34) (emulator) • iPhone 14 (mobile) • 1A122DE2-0CAB-4C3E-A395-691BF27D626F • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 13.0 22A380 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.198 [✓] Network resources • All expected network resources are available. • No issues found! ```
I was able to reproduce and solve by passing a scrollController
to the GridView
and having a listener to update the value of scrolledUnderElevation
The issue was scrolledUnderElevation
is either being used as a minimum of zero and a maximum of 3 by the AppBar
widget, listening to the amount of scroll seems to do the job right.
import 'package:flutter/material.dart';
/// Flutter code sample for [AppBar].
final List<int> _items = List<int>.generate(51, (int index) => index);
void main() => runApp(const AppBarApp());
class AppBarApp extends StatelessWidget {
const AppBarApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorSchemeSeed: const Color(0xff6750a4),
useMaterial3: true,
),
home: const AppBarExample(),
);
}
}
class AppBarExample extends StatefulWidget {
const AppBarExample({super.key});
@override
State<AppBarExample> createState() => _AppBarExampleState();
}
class _AppBarExampleState extends State<AppBarExample> {
ScrollController scrollController = ScrollController();
bool shadowColor = false;
double? scrolledUnderElevation;
@override
void initState() {
super.initState();
scrollController.addListener(_updateScrolledUnderElevation);
}
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
void _updateScrolledUnderElevation() {
setState(() {
// Calculate the amount scrolled under the AppBar based on the scroll offset.
scrolledUnderElevation = scrollController.offset;
});
}
@override
Widget build(BuildContext context) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
final Color evenItemColor = colorScheme.primary.withOpacity(0.15);
return Scaffold(
appBar: AppBar(
title: const Text('AppBar Demo'),
scrolledUnderElevation: scrolledUnderElevation,
shadowColor: shadowColor ? Theme.of(context).colorScheme.shadow : null,
),
body: GridView.builder(
controller: scrollController,
itemCount: _items.length,
padding: const EdgeInsets.all(8.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 2.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
),
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return Center(
child: Text(
'Scroll to see the Appbar in effect.',
style: Theme.of(context).textTheme.labelLarge,
textAlign: TextAlign.center,
),
);
}
return Container(
alignment: Alignment.center,
// tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: _items[index].isOdd ? oddItemColor : evenItemColor,
),
child: Text('Item $index'),
);
},
),
bottomNavigationBar: BottomAppBar(
child: Padding(
padding: const EdgeInsets.all(8),
child: OverflowBar(
overflowAlignment: OverflowBarAlignment.center,
alignment: MainAxisAlignment.center,
overflowSpacing: 5.0,
children: <Widget>[
ElevatedButton.icon(
onPressed: () {
setState(() {
shadowColor = !shadowColor;
});
},
icon: Icon(
shadowColor ? Icons.visibility_off : Icons.visibility,
),
label: const Text('shadow color'),
),
const SizedBox(width: 5),
SafeArea(
bottom: true,
child: ElevatedButton(
onPressed: () {
print('pressed');
if (scrolledUnderElevation == null) {
setState(() {
// Default elevation is 3.0, increment by 1.0.
scrolledUnderElevation = 4.0;
});
} else {
setState(() {
scrolledUnderElevation = scrolledUnderElevation! + 1.0;
});
}
},
child: Text(
'scrolledUnderElevation: ${scrolledUnderElevation ?? 'default'}',
),
),
),
],
),
),
),
);
}
}
https://github.com/flutter/flutter/assets/24737691/d5e26a88-61d6-4673-8d41-267443abe33e
Similar issue #115568
Glad to see Max @md-weber filed this issue. I have had it on my list of things I've been too lazy file for a few months. Well mostly I did not file it, because I have "secret" fix-workaround for it, gotta keep some goodies, haha 😄 Anyway, I'm about to reveal it now.
And @MaxYablochkin your early report of this issue from Nov 2022 is the same issue and first to mention it. You should get the creds for finding it. It was treated as a new feature request back then, but it is in fact a Material-3 design that it should animate. So a spec deviation bug, and indeed, the abrupt change does not look very good at all.
If anybody is interesting, the tint elevation in Material
does contain, as far as I can see, a reasonably correct animation between the M3 elevation tint color values, when Material
s elevation changes, it is all there in the Material
code.
So when Material
is used by AppBar
and we have different non-scrolled-under elevation and scrolled-under elevation values, that it already uses and changes, the color change due to elevation change should already animate, right? Yes, but... as we can all see, it does not do so 🤔
Why is that? I missed it a first too and looked long and hard at the nifty animation code, which of course was the wrong place.
It does not animate because Material
optimizes out this animation if Material
does not use shape
(is null) or has borderRadius
that is null, since then there should be nothing to animate, or so this optimization thinks. Before animation of Material
was only used if it had a shape
or radius
value. This optimization wisely removes a chunk of a bit expensive code on Material
when it is typically not needed, this was fine in M2.
This optimization is here:
When AppBar
is built, and uses Material
, it does not use the borderRadius
property, but it does use shape
here:
This means there is a simple a workaround you can do to make the AppBar
animate correctly.
The flex_color_scheme
package uses it as a "hidden" bonus feature and you can see it in action in the Themes Playground on its AppBar
, it can also be seen in a X/Tweet here
It is a simple one-liner workaround, just give the AppBar
or AppBarTheme
a RoundedRectangleBorder()
and Material
will not optimize out the animation anymore and M3 AppBar
now animates the color change when its elevation changes, thus also when you "scroll-under" 🥳
From FlexColorScheme's AppBarTheme
:
AppBarTheme(
// --- 8< --- Snip --- 8<
// TODO(rydmike): This is a workaround to make tint elevation animate.
// TODO(rydmike): Create issue for none animated AppBar elevation tint.
shape: const RoundedRectangleBorder(),
);
The defaults
for shape
in M3 AppBar
is null, so to get a shape we have to give it one. The const RoundedRectangleBorder()
is still a straight corner zero-radius shape so everything will still look the same, and if we add it to our ThemeData.appBarTheme.shape
we get the tint elevation animation workaround fix on all AppBar
s in our app.
Well, I guess I can remove my own TODO above to make an issue, since it already exists 😄
By the way, the above example with scroll offset is cool and gives a similar result, but it has a slightly different result. There the animation is driven by how fast you scroll/move up or down, which of course is a cool effect. However, based on looking at the Compose demo of an M3 AppBar
, it does not behave like that, it animates independently at fixed duration as soon as it is scrolled under even a tiny bit.
@HansMuller & @TahaTesser, this info might help anybody that wants to fix this issue.
@rydmike Your workaround works great, but it really is something that should be done by default.
@Skyost it is indeed a bug that should be fixed.
I have not checked what the status is on the latest beta 3.22 yet, that will land as the new stable soon (probably May 14). There are a lot of changes to the elevation tint for a lot of widgets.
Most new elevated widgets just use one of the new surface colors as fixed color for elevated state, and elevation tint color is transparent so they don't get anymore tint from elevation.
I did not yet look at how it all affects this scroll under elevation tint in AppBar, might not affect this issue, since the animation is discarded in a lower used Material widget as a part of its optimization. The optimization in question worked well on Material2 but not in Material3, which is why we now have this issue.
@rydmike Apologizes, I'm on stable and therefore, was not aware of these changes. Looking forward this new release 😁
@Skyost as mentioned, I have not checked either how the ColorScheme and elevation changes on master and beta have impacted AppBar, but I will soonish.
I will drop an update on the status of this issue when I do. I doubt it impacts the animation of the scroll under color, it probably only slightly changes the color of the resulting scroll under color, but change to it is probably still instant and not animated as it should be.
Is there an existing issue for this?
Steps to reproduce
Expected results
Material 3 AppBar should animate to a different color
Actual results
Material 3 AppBar changes color without animation
Code sample
Code sample
```dart // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { final String title; const MyHomePage({ Key? key, required this.title, }) : super(key: key); @override StateScreenshots or Video
Screenshots / Video demonstration
[[Material 3 Official Documentation]https://m3.material.io/components/top-app-bar/guidelines#4eab4f50-4a3e-4189-bce2-a46514cde1da](https://m3.material.io/components/top-app-bar/guidelines#4eab4f50-4a3e-4189-bce2-a46514cde1da) Scrolling without animation on an iOS Simulator https://github.com/flutter/flutter/assets/8026644/a6f8683f-7c28-45a4-bbe0-d3250de9b171Logs
No Logs
Flutter Doctor output
Doctor output
```console Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.10.6, on macOS 13.4.1 22F770820d darwin-arm64, locale en-DE) [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2) [✓] Xcode - develop for iOS and macOS (Xcode 14.3.1) [✓] Chrome - develop for the web [✓] Android Studio (version 2022.2) [✓] Android Studio (version 2022.2) [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.4) [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.3) [✓] IntelliJ IDEA Ultimate Edition (version 2023.1.4) [✓] VS Code (version 1.80.1) [✓] Connected device (3 available) [✓] Network resources ```