-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listf: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.r: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
Description
Steps to Reproduce
- Run the code sample at https://dartpad.dev/?id=70f5ce75c3fdb7b614e9253ebd8cc2c9
- Switch between destinations in the
NavigationBar
Expected results:
When switching destinations, the destination icon should animate. The expected result can be produced by uncommenting line 49 in the dartpad example that adds a GlobaKey to the AnimatedIcon.
Actual results:
The icon does not animate and jumps from start to end state.
This issue was introduced with #116888. That change adds a UniqueKey to a widget within NavigationDestination's construction of its icon, which breaks the animated icon's ability to retain state without using a GlobalKey of some sort. Though adding the GlobalKey is a reasonably easy fix to the issue, it's very unintuitive and in my opinion shouldn't be required.
Code sample
(copied from https://dartpad.dev/?id=70f5ce75c3fdb7b614e9253ebd8cc2c9)
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headlineMedium,
),
),
bottomNavigationBar: AnimatedNavigationBar(),
),
);
}
}
class AnimatedNavigationBar extends StatefulWidget {
@override
State<AnimatedNavigationBar> createState() => _AnimatedNavigationBarState();
}
class _AnimatedNavigationBarState extends State<AnimatedNavigationBar> {
int selectedIndex = 0;
@override
Widget build(BuildContext context) => NavigationBar(
selectedIndex: selectedIndex,
onDestinationSelected: (index) => setState(() {
selectedIndex = index;
}),
destinations: [
for (var i = 0; i < 3; i++)
NavigationDestination(
icon: AnimatedIcon(
// Uncomment the following line to fix the bug.
// key: GlobalObjectKey(i),
selected: selectedIndex == i,
),
label: 'Destination$i',
),
],
);
}
class AnimatedIcon extends StatefulWidget {
const AnimatedIcon({super.key, required this.selected});
final bool selected;
@override
State<AnimatedIcon> createState() => _AnimatedIconState();
}
class _AnimatedIconState extends State<AnimatedIcon>
with SingleTickerProviderStateMixin {
late AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
lowerBound: 0.5,
upperBound: 1,
duration: const Duration(seconds: 1),
vsync: this,
);
if (widget.selected) controller.value = 1;
}
@override
void didUpdateWidget(AnimatedIcon oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.selected != oldWidget.selected) {
if (widget.selected) {
controller.forward();
} else {
controller.reset();
}
}
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => ScaleTransition(
scale: controller,
child: const Icon(Icons.favorite),
);
}Internal bug b/273309891
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listf: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.r: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
Type
Projects
Status
Done (PR merged)