感谢@Romain,简单的答案确实是 FittedBox。
当我将 FittedBox 放在第二页上时,将更改 Text Widget 大小的 Hero 转换将是平滑的。
但我需要将原始大小传递到第二页,以使 FittedBox 内的文本显示在与之前显示相同的行数上。
结果如下:
https://vimeo.com/346745092
这里是代码:
import 'package:flutter/material.dart';
const String textThatCouldChangeDependingOnContext = "Hero Text .... ";
main() {
runApp(MaterialApp(home: MyHomePage()));
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey _textKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(64.0),
child: Column(
children: <Widget>[
Hero(
tag: 'tag',
child: Material(
child: Container(
color: Colors.red,
child: Text(textThatCouldChangeDependingOnContext,
key: _textKey),
),
),
),
FlatButton(
child: Text('Fly'),
onPressed: () {
Size originalTextSize = _textKey.currentContext.size;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
MySecondPage(originalTextSize)));
},
)
],
),
),
),
);
}
}
class MySecondPage extends StatefulWidget {
final Size originalTextSize;
MySecondPage(this.originalTextSize);
@override
_MySecondPageState createState() => _MySecondPageState();
}
class _MySecondPageState extends State<MySecondPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
GestureDetector(
onTap: () => Navigator.pop(context),
child: Hero(
tag: 'tag',
transitionOnUserGestures: true,
child: Material(
child: Container(
color: Colors.red,
child: FittedBox(
fit: BoxFit.contain,
child: SizedBox(
height: widget.originalTextSize.height,
width: widget.originalTextSize.width,
child: Text(textThatCouldChangeDependingOnContext),
),
),
),
),
),
)
],
),
),
);
}
}