如何在Flutter中为互换的小部件设置动画? [英] How to animate interchanging widgets in Flutter?

查看:157
本文介绍了如何在Flutter中为互换的小部件设置动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力使自己的想法落到实处. 该设计包含两个文本小部件和一个交换图标,单击它们时,两个文本小部件将以动画方式交换其位置.我尝试堆放并定位,但无法获取.

I am trying to get my head around implementing the below design in flutter. The design consist of two text widgets and an interchange icon on clicking of which both the text widgets will swap their place animatedly. I tried stack and positioned but I could't get it.

推荐答案

您可以使用Stack和Positioned交换两个小部件,最终添加动画效果.我举两个例子: 第一个代码只是交换了两个小部件. 第二个代码示例添加了动画效果.

You can swap two widgets using Stack and Positioned, eventually adding an animation effect. I am giving two examples: the first code simply swaps the two widgets. the second code sample adds an animation effect.

交换两个小部件(无动画)

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final double address1Top = 20;
  final double address2Top = 110;
  bool swapped = false;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 300,
      height: 150,
      color: Colors.blue,
      child: Stack(
        children: <Widget> [
          // Top address
          Positioned(
            top: swapped ? address2Top : address1Top,
            left: 20,
            child: Text("This is the first address"),
          ),
          // Bottom address
          Positioned(
            top: swapped ? address1Top : address2Top,
            left: 20,
            child: Text("This is another address"),
          ),
          // Swap button
          Positioned(
            top: 50,
            right: 20,
            child: FlatButton(
              onPressed: () => setState(() {
                swapped = !swapped;
              }),
              child: Text("swap"),
            ),
          ),
        ],
      ),
    );
  }
}

交换两个带有动画的小部件

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with TickerProviderStateMixin {
  final double address1Top = 20;
  final double address2Top = 110;
  bool swapped = false;

  Animation<double> addressAnimation;
  AnimationController controller;
  animationListener() => setState(() { }); 

  @override
  void didChangeDependencies() async {
    super.didChangeDependencies();

    // Initialize animations
    controller = AnimationController(duration: const Duration(milliseconds: 300), vsync: this);

    addressAnimation = Tween(begin: 0.0, end: address2Top - address1Top).animate(CurvedAnimation(parent: controller, curve: const Interval(0.0, 1.0, curve: Curves.easeInOut)))..addListener(animationListener);
  }

  @override
  dispose() {
    // Dispose of animation controller
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var tweenValue = addressAnimation?.value ?? 0.0;

    return Container(
      width: 300,
      height: 150,
      color: Colors.blue,
      child: Stack(
        children: <Widget> [
          // Top address
          Positioned(
            top: address1Top + tweenValue,
            left: 20,
            child: Text("This is the first address"),
          ),
          // Bottom address
          Positioned(
            top: address2Top - tweenValue,
            left: 20,
            child: Text("This is another address"),
          ),
          // Swap button
          Positioned(
            top: 50,
            right: 20,
            child: FlatButton(
              onPressed: () => setState(() {
                swapped ? controller.reverse() : controller.forward();
                swapped = !swapped;
              }),
              child: Text("swap"),
            ),
          ),
        ],
      ),
    );
  }
}

希望这会有所帮助:)

这篇关于如何在Flutter中为互换的小部件设置动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆