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

ovi*_*i_b 2 animation text transition widget flutter

正如您从 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,
          ),
        ),
      ]),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*tai 5

不要使用单独的TextStyle对象,而是使用来自上下文的某种样式。这样,即使在动画过程中,样式也将基于Theme您的MaterialApp.

对于这两个Text小部件,而不是:

style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
Run Code Online (Sandbox Code Playgroud)

尝试:

style: Theme.of(context).textTheme.headline6, // or some other style
Run Code Online (Sandbox Code Playgroud)

(您将需要删除const关键字,因为它们不再是常量。)

您可以使用 轻松自定义任何内置样式copyWith,例如:

style: Theme.of(context).textTheme.headline6!.copyWith(
  fontSize: 28,
  fontWeight: FontWeight.bold),
Run Code Online (Sandbox Code Playgroud)

一般来说,我认为使用Theme样式是一个很好的做法。