flutter icon indicating copy to clipboard operation
flutter copied to clipboard

Hero animations broken in Router when unrelated page in history is replaced

Open jeduden opened this issue 3 years ago • 6 comments

Steps to Reproduce

  1. Run this sample below.
import 'package:flutter/material.dart';

main() {
  runApp(MyApp());
}

class Parser extends RouteInformationParser<Object>
{
  @override
  Future<Object> parseRouteInformation(RouteInformation routeInformation) {
    return Future.value(routeInformation);
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MaterialApp.router(
        routeInformationParser: Parser(),
        routerDelegate: MyRouterDelegate(),
      ),
    );
  }
}

class MyRouterDelegate extends RouterDelegate<Object>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<Object> {
  int selectedIndex = 0;
  final GlobalKey<NavigatorState> navigatorKey;

  MyRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      observers: [
        HeroController()
      ],
      pages: [
        MaterialPage(
              // To fix hero animations.
              // replace with something stable; ValueKey("BG")
              // or even remove the key
              key: ValueKey('BG-$selectedIndex'),
              child: Scaffold(body:Text("BG"))),
        if (selectedIndex == 0)
          MaterialPage(
              key: ValueKey('0'),
              child: Scaffold(
                body:Text("Page 0"),
                floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
                floatingActionButton: FloatingActionButton(onPressed: (){onNewIndexSelected(1);},child: Icon(Icons.ac_unit),),
              )),
        if (selectedIndex == 1)
          MaterialPage(
              key: ValueKey('1'),
              child: Scaffold(
                body:Text("Page 1"),
                floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
                floatingActionButton: FloatingActionButton(onPressed: (){onNewIndexSelected(0);},child: Icon(Icons.ac_unit),),
              )),
      ],
      onPopPage: (route, result) {
        return false;
      },
    );
  }

  // We don't use named navigation so we don't use this
  @override
  Future<void> setNewRoutePath(configuration) async => null;

  void onNewIndexSelected(int value) {
    selectedIndex = value;
    notifyListeners();
  }
}
  1. Click multiple times on the FAB
  2. Observe there is no FAB hero animation.
  3. Replace key: ValueKey('BG-$selectedIndex'), with key: ValueKey('BG'),
  4. Click multiple times on the FAB
  5. Observe the FAB's hero animations work.

Expected results: Hero animations should work regardless the state of the first unrelated page in the history, since the hero flies between two other pages.

Actual results: Hero animations do not work when the first page in the history is replaced, even though the hero flies between two other pages.

Logs I cropped the output of `flutter run --verbose` since it is too long and doesn't contain errors. If you need a full log - let me know how i can best provide it.
~/d/g/bugâ–¸ flutter run --verbose
[  +95 ms] executing: sysctl hw.optional.arm64
[  +21 ms] Exit code 1 from: sysctl hw.optional.arm64
[        ] sysctl: unknown oid 'hw.optional.arm64'
[   +8 ms] executing: [/usr/local/Caskroom/flutter/1.22.4/flutter/] git -c log.showSignature=false log -n 1 --pretty=format:%H
[  +19 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%H
[        ] f4abaa0735eba4dfd8f33f73363911d63931fe03
[        ] executing: [/usr/local/Caskroom/flutter/1.22.4/flutter/] git tag --points-at f4abaa0735eba4dfd8f33f73363911d63931fe03
[ +143 ms] Exit code 0 from: git tag --points-at f4abaa0735eba4dfd8f33f73363911d63931fe03
[   +2 ms] 2.2.3
[   +7 ms] executing: [/usr/local/Caskroom/flutter/1.22.4/flutter/] git rev-parse --abbrev-ref --symbolic @{u}
[  +10 ms] Exit code 0 from: git rev-parse --abbrev-ref --symbolic @{u}
[        ] origin/stable
[        ] executing: [/usr/local/Caskroom/flutter/1.22.4/flutter/] git ls-remote --get-url origin
[   +8 ms] Exit code 0 from: git ls-remote --get-url origin
[        ] https://github.com/flutter/flutter.git
[ +116 ms] executing: [/usr/local/Caskroom/flutter/1.22.4/flutter/] git rev-parse --abbrev-ref HEAD
[  +16 ms] Exit code 0 from: git rev-parse --abbrev-ref HEAD
[        ] stable
[  +12 ms] executing: sw_vers -productName
[  +24 ms] Exit code 0 from: sw_vers -productName
[        ] macOS
[        ] executing: sw_vers -productVersion
[...snipp....]
[ +234 ms] com.example.bug: 18996
[        ] Waiting for observatory port to be available...
[ +317 ms] Observatory URL on device: http://127.0.0.1:56230/8stfbshExZQ=/
[   +4 ms] Caching compiled dill
[  +81 ms] Connecting to service protocol: http://127.0.0.1:56230/8stfbshExZQ=/
[ +193 ms] Launching a Dart Developer Service (DDS) instance at http://127.0.0.1:0, connecting to VM service at
http://127.0.0.1:56230/8stfbshExZQ=/.
[  +94 ms] DDS is listening at http://127.0.0.1:56235/jUvrcZfxpLQ=/.
[ +105 ms] Successfully connected to service protocol: http://127.0.0.1:56230/8stfbshExZQ=/
[  +28 ms] DevFS: Creating new filesystem on the device (null)
[  +13 ms] DevFS: Created new filesystem on the device
(file:///Users/jeduden/Library/Developer/CoreSimulator/Devices/74779D70-8545-496C-8E00-CA5528E41A7B/data/Containers/Data/Application/1C9
81123-9CB0-4591-9784-F82CC77E22C0/tmp/bugTin5OJ/bug/)
[   +2 ms] Updating assets
[  +92 ms] Syncing files to device iPhone 12 Pro Max...
[   +1 ms] <- reset
[        ] Compiling dart to kernel with 0 updated files
[   +3 ms] <- recompile package:bug/main.dart 5ae49af3-f75a-4aa8-9b1f-66b0a67f7e4a
[        ] <- 5ae49af3-f75a-4aa8-9b1f-66b0a67f7e4a
[ +200 ms] Updating files.
[        ] DevFS: Sync finished
[   +1 ms] Syncing files to device iPhone 12 Pro Max... (completed in 206ms)
[        ] Synced 0.0MB.
[   +2 ms] <- accept
[   +9 ms] Connected to _flutterView/0x7fb4b4020e20.
[   +3 ms] Flutter run key commands.
[   +2 ms] r Hot reload. 🔥🔥🔥
[   +1 ms] R Hot restart.
[        ] h Repeat this help message.
[        ] d Detach (terminate "flutter run" but leave application running).
[        ] c Clear the screen
[        ] q Quit (terminate the application on the device).
[        ] 💪 Running with sound null safety 💪
[        ] An Observatory debugger and profiler on iPhone 12 Pro Max is available at: http://127.0.0.1:56235/jUvrcZfxpLQ=/
[  +33 ms] Activating Dart DevTools...
[+1862 ms] Activating Dart DevTools... (completed in 1,862ms)
[ +623 ms] The Flutter DevTools debugger and profiler on iPhone 12 Pro Max is available at:
                    http://127.0.0.1:9104?uri=http%3A%2F%2F127.0.0.1%3A56235%2FjUvrcZfxpLQ%3D%2F
> flutter analyze                                                                     
Analyzing bug...                                                        
No issues found! (ran in 1.4s)
flutter doctor -v                                                            
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-NL)
    • Flutter version 2.2.3 at /usr/local/Caskroom/flutter/1.22.4/flutter
    • Framework revision f4abaa0735 (7 weeks ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/jeduden/Library/Android/sdk
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = /Users/jeduden/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5, Build version 12E262
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • 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 1.8.0_242-release-1644-b3-6915495)

[✓] VS Code (version 1.59.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.25.0

[✓] Connected device (4 available)
    • iPhone 12 (mobile)         • 21FD38A7-20D4-4062-9886-DCA4F7B5D97A • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5
      (simulator)
    • iPhone 12 Pro (mobile)     • 3444E87E-274F-4A0D-8EC1-E72869232EE9 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5
      (simulator)
    • iPhone 12 Pro Max (mobile) • 74779D70-8545-496C-8E00-CA5528E41A7B • ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-5
      (simulator)
    • Chrome (web)               • chrome                               • web-javascript • Google Chrome 92.0.4515.159
    ! Error: Jan-Eric's iPhone is not connected. Xcode will continue when Jan-Eric's iPhone is connected. (code -13)
    ! Error: Jan-Eric's iPhone is not connected. Xcode will continue when Jan-Eric's iPhone is connected. (code -13)
    ! Error: Jan-Eric's iPhone is not connected. Xcode will continue when Jan-Eric's iPhone is connected. (code -13)

• No issues found!

jeduden avatar Aug 20 '21 14:08 jeduden

Thanks for the detailed report and code sample. Verified on latest stable and master and see the same behavior.

https://user-images.githubusercontent.com/67046386/130431777-a5c00854-ef39-442d-a0ba-4d9080a5b2a7.mov

https://user-images.githubusercontent.com/67046386/130431810-be97ddde-c8b2-4ed0-a2ee-4402de2ee079.mov

stable and master flutter doctor -v
[✓] Flutter (Channel stable, 2.2.3, on Mac OS X 10.15.4 19E2269 darwin-x64,
    locale en-GB)
    • Flutter version 2.2.3 at /Users/dhs/documents/fluttersdk/flutter
    • Framework revision f4abaa0735 (4 days ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30)
    • Android SDK at /Users/dhs/Library/Android/sdk
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Users/dhs/Library/Android/sdk
    • Java binary at: /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.    

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/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
      1.8.0_242-release-1644-b3-6915495)        

[✓] VS Code (version 1.57.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.21.0

[✓] Connected device (4 available)
    • SM G975F (mobile) • RZ8M802WY0X • android-arm64 • Android 10 (API 29)
    • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)            • macos                                •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)               • chrome                               •
      web-javascript • Google Chrome 91.0.4472.114

• No issues found!

[✓] Flutter (Channel master, 2.5.0-7.0.pre.187, on Mac OS X 10.15.4 19E2269
    darwin-x64, locale en-GB)
    • Flutter version 2.5.0-7.0.pre.187 at
      /Users/dhs/documents/fluttersdk/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 05bfbbfbec (4 hours ago), 2021-08-22 21:37:03 -0400
    • Engine revision 710af46d53
    • Dart version 2.15.0 (build 2.15.0-42.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30)
    • Android SDK at /Users/dhs/Library/Android/sdk
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Users/dhs/Library/Android/sdk
    • Java binary at: /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.    

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5.1, Build version 12E507
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Users/dhs/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7486908/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
      1.8.0_242-release-1644-b3-6915495)        

[✓] VS Code (version 1.57.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.21.0

[✓] Connected device (4 available)
    • SM G975F (mobile) • RZ8M802WY0X • android-arm64 • Android 10 (API 29)
    • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)            • macos                                •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)               • chrome                               •
      web-javascript • Google Chrome 91.0.4472.114






darshankawar avatar Aug 23 '21 10:08 darshankawar

It is because the transition delegate place the ValueKey('0') to below ValueKey('BG-1') when updating the pages

so the history stack looks like

[<'1'>] push                   top most
[<'BG-1'>] add
[<'0'>] complete
[<'BG-0'>] complete     bottom

1 is no longer next to 0 so it doesn't trigger the animation. It looks like default transition delegate should alway place the last route before the update next to the new route after the update

chunhtai avatar Aug 27 '21 21:08 chunhtai

It looks like we need a bigger refactor the HeroController. Current HeroController listens to imperactive route change is just not going to work well with declarative page api.

The refactor issue is tracked https://github.com/flutter/flutter/issues/54200

chunhtai avatar Aug 27 '21 23:08 chunhtai

This issue is assigned but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!

flutter-triage-bot[bot] avatar Jul 09 '23 03:07 flutter-triage-bot[bot]

This issue was assigned to @chunhtai but has had no status updates in a long time. To remove any ambiguity about whether the issue is being worked on, the assignee was removed.

flutter-triage-bot[bot] avatar Aug 15 '23 21:08 flutter-triage-bot[bot]

This issue is assigned to @chunhtai but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!

flutter-triage-bot[bot] avatar May 01 '24 21:05 flutter-triage-bot[bot]