Flutter Hero动画不用主题色?
Flutter Hero animation does not use theme colors?
在 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();
},
),
),
),
]
),
);
}
}
发生这种情况是因为 Hero
的飞行动画是 MaterialApp
上的 OverlayEntry
。
因此,虽然使用的小部件相同(图标),但其位置不同。
问题是,在您的情况下 IconTheme.of(context)
returns 基于该位置的不同值:
- 作为
AppBar
的子项,IconTheme
被覆盖以将 primaryColor
作为背景处理
- 在其他任何地方,它都使用
MaterialApp
上指定的默认主题。
所以在动画的时候,使用的IconTheme
是不同的,导致了这个问题。
一个潜在的解决方案是修复该值以确保使用的 IconTheme
始终相同:
AppBar(
leading: Builder(
builder: (context) {
return Hero(
child: IconTheme(
data: Theme.of(context).primaryIconTheme,
child: Icon(Icons.whatshot),
),
);
},
),
);
在 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();
},
),
),
),
]
),
);
}
}
发生这种情况是因为 Hero
的飞行动画是 MaterialApp
上的 OverlayEntry
。
因此,虽然使用的小部件相同(图标),但其位置不同。
问题是,在您的情况下 IconTheme.of(context)
returns 基于该位置的不同值:
- 作为
AppBar
的子项,IconTheme
被覆盖以将primaryColor
作为背景处理 - 在其他任何地方,它都使用
MaterialApp
上指定的默认主题。
所以在动画的时候,使用的IconTheme
是不同的,导致了这个问题。
一个潜在的解决方案是修复该值以确保使用的 IconTheme
始终相同:
AppBar(
leading: Builder(
builder: (context) {
return Hero(
child: IconTheme(
data: Theme.of(context).primaryIconTheme,
child: Icon(Icons.whatshot),
),
);
},
),
);