Flutter AnimatedSwitcher 实现优美的图片切换动画

Posted 早起的年轻人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter AnimatedSwitcher 实现优美的图片切换动画相关的知识,希望对你有一定的参考价值。

志在巅峰的攀登者,不会陶醉在沿途的某个脚印之中,在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。

如果你有兴趣 你可以关注一下公众号 biglead 来获取最新的学习资料。

Flutter 用来快速开发 android ios平台应用,在Flutter 中,通过 AnimatedSwitcher 来实现 Widget 动画切换效果

更多Widget 的应用,小编已总结在书中


本文章的最终效果


1 图片资源

我在这里给大家提供两个svg的图,当然需要使用一个SVG的插件

  flutter_svg: ^0.22.0

<?xml version="1.0" encoding="UTF-8"?>
<svg width="53px" height="53px" viewBox="0 0 53 53" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>Left door lock</title>
    <g id="App" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Car-Lock" transform="translate(-32.000000, -398.000000)" fill="#FF5368">
            <g id="Lockers" transform="translate(21.000000, 207.000000)">
                <g id="Left-door-lock" transform="translate(0.000000, 180.000000)">
                    <circle id="Oval-2" stroke="#FF5368" stroke-width="2.25" fill-opacity="0.15" cx="37.5" cy="37.5" r="24.75"></circle>
                    <path d="M37.875,28.5002796 C40.3537914,28.4734105 42.75,30.3887298 42.75,31.9470345 L42.75,35.7767623 C43.5784271,35.7767623 44.25,36.4483352 44.25,37.2767623 L44.25,45 C44.25,45.8284271 43.5784271,46.5 42.75,46.5 L33,46.5 C32.1715729,46.5 31.5,45.8284271 31.5,45 L31.5,37.2767623 C31.5,36.4483352 32.1715729,35.7767623 33,35.7767623 L33,31.9470345 L33,31.9470345 C33,30.4415571 35.4802408,28.5262377 37.875,28.5002796 Z M37.875,39.60649 C37.2536797,39.60649 36.75,40.1208783 36.75,40.7554084 C36.75,41.2238352 37.0244944,41.6267873 37.418173,41.8056527 L37.125,44.2021633 L38.625,44.2021633 L38.3328052,41.8052076 C38.7259603,41.6261195 39,41.2234471 39,40.7554084 C39,40.1208783 38.4963203,39.60649 37.875,39.60649 Z M37.875,30.7981162 C36.5541465,30.7903939 35.25,31.5074769 35.25,32.7129801 L35.25,32.9649168 C35.25,32.9987014 35.25,33.0344166 35.25,33.0720623 L35.25,35.2937555 L35.25,35.2937555 L40.5,35.776 L40.5,32.7129801 L40.5,32.7129801 C40.5,31.5228232 39.1790388,30.8057402 37.875,30.7981162 Z" id="Combined-Shape"></path>
                </g>
            </g>
        </g>
    </g>
</svg>

<?xml version="1.0" encoding="UTF-8"?>
<svg width="53px" height="53px" viewBox="0 0 53 53" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>Left door unlock</title>
    <g id="App" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Car-Unlock" transform="translate(-32.000000, -398.000000)" fill="#53F9FF">
            <g id="Lockers" transform="translate(21.000000, 207.000000)">
                <g id="Left-door-unlock" transform="translate(0.000000, 180.000000)">
                    <circle id="Oval-2" stroke="#53F9FF" stroke-width="2.256" fill-opacity="0.15" cx="37.5" cy="37.5" r="24.75"></circle>
                    <path d="M41.625,28.5002796 C44.1037914,28.4734105 46.5,30.3887298 46.5,31.9470345 L46.5,37.3086534 L46.5,37.3086534 C46.0013843,37.5639686 45.6263843,37.6916262 45.375,37.6916262 C45.1236157,37.6916262 44.7486157,37.5639686 44.25,37.3086534 L44.25,32.7129801 L44.25,32.7129801 C44.25,31.5228232 42.9290388,30.8057402 41.625,30.7981162 C40.3041465,30.7903939 39,31.5074769 39,32.7129801 L39,35.776 L39.1328947,35.7829086 C39.8993762,35.8520659 40.5,36.4962725 40.5,37.2807623 L40.5,44.996 C40.5,45.8266363 39.8266363,46.5 38.996,46.5 L29.254,46.5 C28.4233637,46.5 27.75,45.8266363 27.75,44.996 L27.75,37.2807623 C27.75,36.450126 28.4233637,35.7767623 29.254,35.7767623 L36.75,35.776 L36.75,31.9470345 L36.75,31.9470345 C36.75,30.4415571 39.2302408,28.5262377 41.625,28.5002796 Z M34.125,39.60649 C33.5036797,39.60649 33,40.1208783 33,40.7554084 C33,41.2238352 33.2744944,41.6267873 33.668173,41.8056527 L33.375,44.2021633 L34.875,44.2021633 L34.5828052,41.8052076 C34.9759603,41.6261195 35.25,41.2234471 35.25,40.7554084 C35.25,40.1208783 34.7463203,39.60649 34.125,39.60649 Z" id="Combined-Shape"></path>
                </g>
            </g>
        </g>
    </g>
</svg>

当然你需要在配置文件中进行配置

2 核心动画效果组件

class DoorLock extends StatelessWidget {
  const DoorLock({
    Key? key,
    required this.press,
    required this.isLock,
  }) : super(key: key);

  final VoidCallback press;
  final bool isLock;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: press,
      child: AnimatedSwitcher(
        //动画时间
        duration:  Duration(milliseconds: 300),
        //动画曲线
        switchInCurve: Curves.easeInOutBack,
        //动画方式 这里使用中心缩放
        transitionBuilder: (child, animation) => ScaleTransition(
          scale: animation,
          child: child,
        ),
        //动画切换显示的子Widget
        child: isLock
            ? SvgPicture.asset(
                "assets/svg/door_lock.svg",
                key: ValueKey("lock"),
              )
            : SvgPicture.asset(
                "assets/svg/door_unlock.svg",
                key: ValueKey("unlock"),
              ),
      ),
    );
  }
}

3 外部引用


main(){
  runApp(MaterialApp(home: TestDoorLockPage(),));
}

class TestDoorLockPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return TestDoorLockPageState();
  }
}

class TestDoorLockPageState extends State<TestDoorLockPage> {
  bool _isLock = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("测试"),
      ),
      body: Center(
        child: DoorLock(
          press: () {
            setState(() {
              _isLock=!_isLock;
            });
          },
          isLock: _isLock,
        ),
      ),
    );
  }
}

以上是关于Flutter AnimatedSwitcher 实现优美的图片切换动画的主要内容,如果未能解决你的问题,请参考以下文章

Flutter小说分页效果实现

带有 IndexedStack 的 AnimatedSwitcher

AnimatedSwitcher 没有动画

AnimatedSwitcher 没有按预期工作?小部件更改但没有动画

Flutter 敲一个灵动的录音按钮动画 - Speed Code

Flutter 敲一个灵动的录音按钮动画 - Speed Code