Flutter中Hero动画过渡时文本丢失样式的问题求助
解决Flutter Hero动画中文本样式丢失的问题
问题核心是:Text组件在Hero过渡动画中丢失自定义样式,而Container的动画正常。这是因为目标页面中,AppBar的Title会自带默认文本样式,覆盖了你设置的Text样式,导致过渡过程中样式被替换。
解决方案:用Material包裹Hero内的Text组件
在源页面和目标页面的Hero包裹的Text外层,添加Material组件并设置透明背景,隔离父组件的样式影响,确保自定义样式在动画过程中保持一致。
修改后的完整代码
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', // 用Material包裹Text,隔离样式影响 child: Material( color: Colors.transparent, 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: Hero( tag: 'text', // 同样用Material包裹Text child: Material( color: Colors.transparent, child: const Text( "MY HEADER", style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold), ), ), ), ), body: Stack(children: [ Hero( tag: 'box', child: Container( color: Colors.amber, ), ), ]), ); } }
原理说明
Hero动画过渡时,会将源组件的视觉属性平滑过渡到目标组件。但如果目标组件处于AppBar这类带有默认文本样式的父组件中,Text的自定义样式会被父组件的样式覆盖。用Material包裹Text后,相当于给Text创建了一个独立的样式上下文,避免父组件的样式干扰,从而保证动画过程中样式一致。
内容的提问来源于stack exchange,提问作者ovi_b
相关产品推荐
相关产品推荐

