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

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

前言

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

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

正文

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 的顶部,您就会看到一个十分漂亮的效果

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

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(0, 1),
            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 状况改变时,动画将呈现,按钮的内部将被涂成赤色。这里最重要的部分是要害作业。假如您不这样做,系统将检测到两个相同的动画将不会呈现。

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

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(-1, 0),
            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 在项目中使用动画(不使用包)

此外,我想提出一个批判。假如不运用动画,页面转换在 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 。

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

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 中显现这一点。也许是竞选宣言。我把你留给你的想象力,所有你要做的便是仿制动画相关的代码,并发挥他们:)

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

代码

github.com/bedirhanssa…

结束语

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

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

祝你有一个夸姣的一天~


猫哥

  • 微信 ducafecat

  • wiki.ducafecat.tech

  • video.ducafecat.tech