预热程序

一个用于通用处理动画预热的库

更新

iOS 渲染卡顿问题与着色器预编译有关,如此处所述,现在已基本缓解。非常感谢 Flutter 团队!

预热程序

一个用于通用处理动画预热的库,如在https://github.com/flutter/flutter/issues/76180中讨论的。

此解决方案对于具有许多需要预热动画的应用程序来说,可扩展性不高,主要用作应用程序在可用更永久的解决方案之前,可以用来预热动画的一种方法示例。

用法

预热叠加层

预热动画最常见的方法是在应用程序启动时执行动画的伪启动屏幕。

import 'package:warmup_routine/warmup_overlay.dart';
import 'package:warmup_routine/warmup_animation.dart';

// Example of showing an overlay under which the animations are executing.
class WarmupOverlayExample extends StatefulWidget {
  _WarmupOverlayExampleState createState() => _WarmupOverlayExampleState();
}

class _WarmupOverlayExampleState extends State<WarmupOverlayExample> {
  bool _shouldShowOverlay = true;

  @override
  Widget build(BuildContext context) {
    if (_shouldShowOverlay) {
      return WarmupOverlay(
        onComplete: () {
          setState(() {
            _shouldShowOverlay = false;
          });
        },
        builder: (context) {
          return Container(
            child: Center(
              child: CircularProgressIndicator(),
            ),
          );
        },
        animations: [
          WarmupAnimation(
            builder: (context, complete) {
              // Replace with your animation of choice
              return OpenContainerAnimation(onComplete: complete);
            },
            repeat: 4,
          ),
        ],
      );
    }
  } else {
    // Start rest of application
    MyApp();
  }
}

预热程序

如果不需要叠加层,可以在现有代码中的任何位置执行预热程序

class WarmupRoutineExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return WarmupRoutine(
      animations: [
        WarmupAnimation(
          builder: (context, complete) {
            // Replace with your animation of choice
            return OpenContainerAnimation(onComplete: complete);
          },
          repeat: 4,
        ),
      ],
      onComplete: () {
        // Start rest of application
      },
    );
  }
}
// The overlay will remain on top of the application above navigation events, so Navigator.push/pop
// can be warmed up as well:

class NavigationWarmupScreen extends StatefulWidget {
  final Function onComplete;

  NavigationWarmupScreen({@required this.onComplete});

  _NavigationWarmupScreenState createState() => _NavigationWarmupScreenState();
}

class _NavigationWarmupScreenState extends State<NavigationWarmupScreen> {
  initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (BuildContext context) {
            return YourWidget();
          },
          fullscreenDialog: true,
        ),
      );

      Future.delayed(
        // Adjust duration as needed
        Duration(milliseconds: 400),
        () {
          Navigator.pop(context);
          Future.delayed(
            Duration(milliseconds: 400),
            () {
              widget.onComplete();
            },
          );
        },
      );
    });
  }

  @override
  build(context) {
    return Container();
  }
}

class WarmupOverlayNavigationExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return WarmupOverlay(
      onComplete: () {
        // Start rest of application
      },
      builder: (context) {
        return Container(
          child: Center(
            child: CircularProgressIndicator(),
          ),
        );
      },
      animations: [
        WarmupAnimation(
          builder: (context, complete) {
            return NavigationWarmupScreen(onComplete: complete);
          },
          repeat: 2,
        ),
      ],
    );
  }
}

完整示例在GitHub 仓库

GitHub

https://github.com/danReynolds/warmup_routine