Flutter Hero 动画不使用主题颜色?

Jes*_*Wit 1 flutter flutter-animation

当在 MaterialApp 的应用栏中创建带有图标的简单英雄动画时,英雄动画似乎不使用主题颜色,除非在图标本身中显式指定颜色。有人可以解释为什么在未明确设置图标颜色的情况下图标的颜色在飞行过程中发生变化吗?英雄无法访问主题数据吗?或者它使用其他颜色集?

例子:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Hero(
          tag: "mytag",
          child: Material(
            color: Colors.transparent,
            child: IconButton(
              icon: Icon(
                Icons.menu,
                // uncomment below line and the flying icon is white as expected...
                // color: Theme.of(context).primaryIconTheme.color
              ),
              onPressed: () {
                Navigator.of(context).push(
                  PageRouteBuilder(
                    pageBuilder: 
                      (context, animation, secondaryAnimation) => SecondPage()
                  )
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget> [
          Hero(
            tag: "mytag",
            child: Material(
              color: Colors.transparent,
                child: IconButton(
                icon: Icon(
                  Icons.menu,
                  // uncomment below line and the reverse flying icon is white as expected...
                  // color: Theme.of(context).primaryIconTheme.color
                ),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ),
          ),
        ]
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Rém*_*let 6

发生这种情况是因为 的飞行动画HeroOverlayEntry开启的MaterialApp。因此,虽然使用的小部件是相同的(图标),但它的位置却不同。

问题是,在您的情况下,IconTheme.of(context)根据该位置返回不同的值:

  • 作为 的子级AppBar,被重写以作为背景IconTheme处理primaryColor
  • 在其他地方,它使用 上指定的默认主题MaterialApp

因此在动画过程中,IconTheme使用的是不同的,导致了这样的问题。


一个潜在的解决方案是修复该值以确保IconTheme使用的值始终相同:

AppBar(
  leading: Builder(
    builder: (context) {
      return Hero(
        child: IconTheme(
          data: Theme.of(context).primaryIconTheme,
          child: Icon(Icons.whatshot),
        ),
      );
    },
  ),
);
Run Code Online (Sandbox Code Playgroud)