Reputation: 169
As you can see from the gif and from the code below I have a container and a text widget, both wrapped in a hero widget.
When the container is clicked the second page opens. I would like to have a hero animation for both widgets.
The animations of the container works great. The text however seems to lose the style while the transition is happening.
Any idea on how to fix it?
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomeScreen(),
routes: {
HomeScreen.routName: (context) => const HomeScreen(),
SecondSceen.routeName: (context) => const SecondSceen(),
},
);
}
}
class HomeScreen extends StatelessWidget {
static const routName = '/home-screen';
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: [
Align(
alignment: Alignment.bottomCenter,
child: InkWell(
onTap: () => Navigator.of(context).pushNamed(SecondSceen.routeName),
child: Hero(
tag: 'box',
child: Container(
color: Colors.amber,
width: MediaQuery.of(context).size.width * 0.8,
height: 210,
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
height: 210,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 8, 16),
child: Column(
children: const [
Hero(
tag: 'text',
child: Text(
"MY HEADER",
style:
TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
),
],
),
),
),
),
]),
);
}
}
class SecondSceen extends StatelessWidget {
static const routeName = '/note-screen';
const SecondSceen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
foregroundColor: Colors.black,
centerTitle: true,
title: const Hero(
tag: 'text',
child: Text(
"MY HEADER",
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
),
),
body: Stack(children: [
Hero(
tag: 'box',
child: Container(
color: Colors.amber,
),
),
]),
);
}
}
Upvotes: 6
Views: 2784
Reputation: 26
DefaultTextStyle(
style: AppTextStyle.subtitle1.copyWith(
fontWeight: AppFontWeight.medium,
color: AppColors.textColor,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
child: Text(
isCurrentUser ? currentUserState.username : userModel.username,
),
),
Upvotes: 0
Reputation: 709
It is a known Flutter issue. Someone posted a solution here. Good for anyone who may have the same question in the future: https://github.com/flutter/flutter/issues/30647#issuecomment-480980280
Widget _flightShuttleBuilder(
BuildContext flightContext,
Animation<double> animation,
HeroFlightDirection flightDirection,
BuildContext fromHeroContext,
BuildContext toHeroContext,
) {
return DefaultTextStyle(
style: DefaultTextStyle.of(toHeroContext).style,
child: toHeroContext.widget,
);
}
...
Widget build(BuildContext context) {
return Scaffold(
...
child: Hero(
tag: 'text',
flightShuttleBuilder: _flightShuttleBuilder,
child: Text('Text'),
),
Upvotes: 2
Reputation: 692
Just adding a Material
as the child to Hero
as shown below.
Hero(
tag:'box',
child: Material(// wrap with Material
type: MaterialType.transparency, // likely needed
child: Container(... // content
Happy Coding!!
Upvotes: 6
Reputation: 9789
Instead of using individual TextStyle
objects, use some style coming from the context. This way even during the animation, the styles will be based on the Theme
of your MaterialApp
.
For both Text
widgets, instead of:
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
try:
style: Theme.of(context).textTheme.headline6, // or some other style
(You will need to remove const
keywords because these are no longer constants.)
You can easily customize any built in style using copyWith
, for example:
style: Theme.of(context).textTheme.headline6!.copyWith(
fontSize: 28,
fontWeight: FontWeight.bold),
In general it is a good practice in my opinion to use Theme
styles.
Upvotes: 10