会煮咖啡的猫

V1

2022/11/17阅读:11主题:凝夜紫

Flutter 在项目中使用动画(不使用包)

Flutter 在项目中使用动画(不使用包)

前言

动画对于 web 和移动应用程序都非常重要。但是在移动应用程序中不应该使用夸张的动画。简单但是很多动画使你的应用程序更好用。以至于当你点击一个按钮时,一种平滑的感觉或者页面过渡都会影响到你。

正文

1 按下按钮柔软的感觉

class _CustomButtonState extends State<CustomButton>
    with SingleTickerProviderStateMixin 
{
  late double _scale;
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 350),
      lowerBound: 0.0,
      upperBound: 0.1,
    )..addListener(() {
        setState(() {});
      });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _tapDown(TapDownDetails details) {
    _controller.forward();
  }

  void _tapUp(TapUpDetails details) {
    _controller.reverse();
  }

  @override
  Widget build(BuildContext context) {
    _scale = 1 - _controller.value;
    return GestureDetector(
      onTap: widget.onTap,
      onTapDown: _tapDown,
      onTapUp: _tapUp,
      child: Transform.scale(
        scale: _scale,
        child:

首先,我们创建一个名为 CustomButton 的 StatewWidget。我们将在应用程序的任何地方使用这个按钮。也许宽度,里面的文字会改变。在最后一个子部分之后,我们将设计我们的按钮。(我不想在这里占用太多的空间,你可以在文章的最后找到完成项目的源代码)。

在我们看到模拟器中的动画之前,我们还有一个场景。当我们按下这个按钮时,我们希望出现一个弹出窗口。弹出窗口突然出现在 Flutter 的屏幕上。同样,我们可以通过使用动画给人一种柔软的感觉。请确保您的应用程序将更加专业和吸引眼球的方式:)

return showGeneralDialog(
    context: context,
    pageBuilder: (context, animation, secondaryAnimation) {
      return ScaleTransition(
        scale: Tween<double>(begin: 0.5, end: 1).animate(animation),
        child: AlertDialog(

只要将这些 widget 包装在 AlertDialog 的顶部,您就会看到一个非常漂亮的效果

2 想要一个像 Instagram 一样的喜欢按钮吗?

class _FavoritesButtonState extends State<FavoritesButton>
    with SingleTickerProviderStateMixin 
{
  bool isFavorite = false;
  late final AnimationController _controller = AnimationController(
      vsync: this, duration: const Duration(milliseconds: 300));

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 10.h,
      width: 10.w,
      decoration: const BoxDecoration(
        shape: BoxShape.circle,
        color: Colors.white,
        boxShadow: [
          BoxShadow(
            offset: Offset(01),
            color: Colors.grey,
            blurRadius: 1,
          ),
        ],
      ),
      child: AnimatedBuilder(
          animation: _controller,
          builder: (context, child) => GestureDetector(
                child: isFavorite
                    ? AnimatedSwitcher(
                        switchInCurve: Curves.easeInOutBack,
                        transitionBuilder: (child, animation) =>
                            ScaleTransition(
                              scale: animation,
                              child: child,
                            ),
                        duration: const Duration(milliseconds: 300),
                        child: Icon(
                          Icons.favorite,
                          size: 3.7.h,
                          color: Colors.red,
                          key: const ValueKey('isFav'),
                        ))
                    : AnimatedSwitcher(
                        switchInCurve: Curves.easeInOutBack,
                        transitionBuilder: (child, animation) =>
                            ScaleTransition(
                          scale: animation,
                          child: child,
                        ),
                        duration: const Duration(milliseconds: 300),
                        child: Icon(
                          Icons.favorite_border_outlined,
                          size: 3.7.h,
                          color: Colors.grey,
                          key: const ValueKey('isNotFav'),
                        ),
                      ),
                onTap: () {
                  setState(() {
                    isFavorite = !isFavorite;
                  });
                },
              )),
    );
  }
}

当 isFavorite 状态改变时,动画将出现,按钮的内部将被涂成红色。这里最重要的部分是关键作业。如果您不这样做,系统将检测到两个相同的动画将不会出现。

3 动画页面过渡

实际上,这里有一个包依赖项。不过别担心,这是必要的。因为在 Flutter Navigator.push() 等方法现在是原始的。我强烈推荐使用 GoRoute 或 AutoRoute。在本文中,我们将讨论 GoRoute 中可用的动画。

import 'package:animations/view/empty/empty_view.dart';
import 'package:animations/view/home/home_view.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

animationPage({required GoRouterState state, required Widget route}) =>
    CustomTransitionPage<void>(
      key: state.pageKey,
      child: route,
      transitionsBuilder: (BuildContext context, Animation<double> animation,
              Animation<double> secondaryAnimation, Widget child) =>
          SlideTransition(
        position: animation.drive(
          Tween<Offset>(
            begin: const Offset(-10),
            end: Offset.zero,
          ).chain(CurveTween(curve: Curves.fastOutSlowIn)),
        ),
        child: child,
      ),
    );

final routes = GoRouter(
  initialLocation: '/home',
  debugLogDiagnostics: true,
  routes: [
    GoRoute(
      path: '/home',
      pageBuilder: (context, state) {
        return animationPage(
          state: state,
          route: const HomeView(),
        );
      },
      routes: [
        GoRoute(
          path: 'empty',
          pageBuilder: (context, state) {
            return animationPage(
              state: state,
              route: const EmptyView(),
            );
          },
        ),
      ],
    ),
  ],
);

下面是将执行主要工作的方法 animationPage() 。我们用这种方法包装相关页面并完成工作。您可以通过更改 start: const Offset (-1,0)值来实现不同的动画。我想像书页一样过渡。这就是它看起来的样子

此外,我想提出一个批评。如果不使用动画,页面转换在 Flutter 中是非常粗糙的。

4 动画文字

通过您现在将看到的动画,您可以在页面首次打开时显示可滚动的文本。闲话少说,让我们检查一下代码,然后讨论一下我们能做些什么。

class _AnimatedTextState extends State<AnimatedText>
    with TickerProviderStateMixin 
{
  late final AnimationController _controller = AnimationController(
    duration: const Duration(seconds: 3),
    vsync: this,
  )..forward();
  late final Animation<double> _animation = CurvedAnimation(
    parent: _controller,
    curve: Curves.fastOutSlowIn,
  );

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizeTransition(
      sizeFactor: _animation,
      axis: Axis.horizontal,
      axisAlignment: -1,
      child: CustomText(
        widget.text,
        textStyle: widget.textStyle,
      ),
    );
  }
}

我想让你注意两件事。第一个是。.正向()方法正向()方法。这表示当打开该页面时,该动画仅显示一次。如果用 repeat() 替换它,它将是连续的。第二,轴对齐参数。我做了这个 -1。文本从左到右。如果我做 1,它会是相反的。这是我最喜欢的动画。您可以将此动画应用于除 Text 之外的许多其他 widget 。

5 更改/闪动文本样式

class ChangingText extends StatefulWidget {
  const ChangingText(this.text, {super.key});

  final String text;

  @override
  State<ChangingText> createState() => _ChangingTextState();
}

class _ChangingTextState extends State<ChangingText>
    with TickerProviderStateMixin 
{
  late AnimationController _controller;
  late TextStyleTween _styleTween;
  late CurvedAnimation _curvedAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 750),
      vsync: this,
    )..repeat(reverse: true);
    _styleTween = TextStyleTween(
      begin: GoogleFonts.poppins(
        fontSize: 15.sp,
        color: AppConstants.java,
      ),
      end: TextStyle(
        fontSize: 15.sp,
        color: AppConstants.bittersweet,
      ),
    );
    _curvedAnimation = CurvedAnimation(
      parent: _controller,
      curve: Curves.elasticInOut,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: DefaultTextStyleTransition(
        style: _styleTween.animate(_curvedAnimation),
        child: CustomText(widget.text),
      ),
    );
  }
}

我在这里使用了 repeat() 。这意味着它将连续运行。您可以在要显示给用户的文本、按钮、卡片 widget 中显示这一点。也许是竞选宣言。我把你留给你的想象力,所有你要做的就是复制动画相关的代码,并发挥他们:)

代码

https://github.com/bedirhanssaglam/flutter-animations

结束语

如果本文对你有帮助,请转发让更多的朋友阅读。

也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。

祝你有一个美好的一天~


© 猫哥

  • 微信 ducafecat

  • https://wiki.ducafecat.tech

  • https://video.ducafecat.tech

分类:

移动端开发

标签:

Android

作者介绍

会煮咖啡的猫
V1

flutter node go dock