Flutter 在更改主题亮度时禁用 AnimatedContainer 的动画

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

如果您在 AnimatedContainer 中使用依赖于亮度的颜色(例如 Theme.of(context).colorScheme.onBackground,对于深色主题为白色,对于浅色主题为黑色)并更改应用程序亮度,则 AnimatedContainer 还会根据提供的 Duration 对其颜色进行动画处理带有主题切换动画。如何从 AnimatedContainer 中禁用此附加动画?

左图是一个 AnimatedContainer,右图是一个默认容器

enter image description here

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

ValueNotifier<ThemeData> _theme = ValueNotifier(
  ThemeData(brightness: Brightness.dark, backgroundColor: Colors.white),
);

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<ThemeData>(
      valueListenable: _theme,
      builder: (_, theme, __) => MaterialApp(
        theme: theme,
        title: 'Material App',
        home: _Scaffold(),
      ),
    );
  }
}

class _Scaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Material App Bar'),
        backgroundColor: Theme.of(context).backgroundColor,
      ),
      backgroundColor: Colors.red,
      body: Center(
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                AnimatedContainer(
                  curve: Curves.easeInOutCubic,
                  duration: const Duration(milliseconds: 175),
                  color: Theme.of(context).backgroundColor,
                  width: 50.0,
                  height: 50.0,
                  margin: const EdgeInsets.all(10.0),
                ),
                Container(
                  color: Theme.of(context).backgroundColor,
                  width: 50.0,
                  height: 50.0,
                ),
              ],
            ),
            ElevatedButton(
              onPressed: () {
                final Brightness newBrightness =
                    _theme.value.brightness == Brightness.dark
                        ? Brightness.light
                        : Brightness.dark;
                _theme.value = _theme.value.copyWith(
                  brightness: newBrightness,
                  backgroundColor: newBrightness == Brightness.dark
                      ? Colors.white
                      : Colors.black,
                );
              },
              child: const Text('switch brightness'),
            ),
          ],
        ),
      ),
    );
  }
}
flutter animation themes brightness animatedcontainer
1个回答
0
投票

最终,除了这个之外,我没有找到任何更好的解决方案:

您为每个动画容器提供一个密钥,如下所示:

      key: !isThemeAnimationInProgress
                                ? null // Or your own ValueKey if needed, applies once theme animation is ended
                                : UniqueKey(), // Applies only during theme transition

在你的主题切换回调中添加这个

/// If theme animation is currently in progress, this is set to true
bool isThemeAnimationInProgress = false;

/// Keeps track of theme animation transition.
Timer? _timer;
  isThemeAnimationInProgress = true;

  // In case some widget needs to know if theme switch is in progress
  _timer?.cancel();
  _timer = Timer(kThemeAnimationDuration, () {
    isThemeAnimationInProgress = false;
  });
© www.soinside.com 2019 - 2024. All rights reserved.