Flutter 中英雄动画期间文本失去样式

问题描述 投票:0回答:2

正如您从 gif 和下面的代码中看到的,我有一个容器和一个文本小部件,它们都包装在一个英雄小部件中。

单击容器时,将打开第二页。我想要两个小部件都有一个英雄动画。

容器的动画效果很棒。然而,在过渡发生时,文本似乎失去了风格。

知道如何修复它吗?

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,
          ),
        ),
      ]),
    );
  }
}
flutter animation text widget transition
2个回答
5
投票

不要使用单独的

TextStyle
对象,而是使用来自上下文的某种样式。这样,即使在动画期间,样式也将基于您的
Theme
MaterialApp

对于两个

Text
小部件,而不是:

style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),

尝试:

style: Theme.of(context).textTheme.headline6, // or some other style

(您需要删除

const
关键字,因为它们不再是常量。)

您可以使用

copyWith
轻松自定义任何内置样式,例如:

style: Theme.of(context).textTheme.headline6!.copyWith(
  fontSize: 28,
  fontWeight: FontWeight.bold),

总的来说,我认为使用

Theme
样式是一个很好的做法。


0
投票

这是一个已知的 Flutter 问题。有人在这里发布了解决方案。对于将来可能有同样问题的任何人都有好处: 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'),
        ),
© www.soinside.com 2019 - 2024. All rights reserved.