如何为连续2个项目的交换设置动画? [英] How to animate the swap of 2 items in a Row?

查看:26
本文介绍了如何为连续2个项目的交换设置动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使事情变得非常简单.有一个带有2个小部件的 Row .当我按下按钮时,他们交换订单.我希望该订单交换动画化.

I want to make something very simple. There's a Row with 2 widgets. When I press a button, they swap orders. I want this order swap to be animated.

我看过 AnimatedPositioned ,但它需要堆栈.做这种事情的最好方法是什么?

I've loked at AnimatedPositioned but it requires a Stack. What would be the best way of doing such thing?

我认为在Flutter中跨行单元的动画位置回答了这个问题但这是另一个不同的问题

I thought Animating position across row cells in Flutter answered this but it's another different problem

推荐答案

您可以使用 DartPad

You can easily animate widgets in a Row with SlideAnimation. Please see the code below or you may directly run the code on DartPad https://dartpad.dev/e5d9d2c9c6da54b3f76361eac449ce42 Just tap on the colored box to swap their positions with an slide animation.

SlideAnimation

SlideAnimation

使小部件相对于其正常位置的位置动起来.

Animates the position of a widget relative to its normal position.

平移表示为按孩子的大小缩放的偏移量.例如,dx为0.25的偏移将导致水平是孩子宽度的四分之一的翻译.

The translation is expressed as an Offset scaled to the child's size. For example, an Offset with a dx of 0.25 will result in a horizontal translation of one quarter the width of the child.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  List<Animation<Offset>> _offsetAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );
    _offsetAnimation = List.generate(
      2,
      (index) => Tween<Offset>(
        begin: const Offset(0.0, 0.0),
        end: Offset(index == 0 ? 1 : -1, 0.0),
      ).animate(_controller),
    );
  }

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

  void _animate() {
    _controller.status == AnimationStatus.completed
        ? _controller.reverse()
        : _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Flutter Demo Row Animation")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                BoxWidget(
                  callBack: _animate,
                  text: "1",
                  color: Colors.red,
                  position: _offsetAnimation[0],
                ),
                BoxWidget(
                  callBack: _animate,
                  text: "2",
                  color: Colors.blue,
                  position: _offsetAnimation[1],
                )
              ],
            ),
            RaisedButton(
              onPressed: _animate,
              child: const Text("Swap"),
            )
          ],
        ),
      ),
    );
  }
}

class BoxWidget extends StatelessWidget {
  final Animation<Offset> position;
  final Function callBack;
  final String text;
  final Color color;

  const BoxWidget(
      {Key key, this.position, this.callBack, this.text, this.color})
      : super(key: key);
  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: position,
      child: GestureDetector(
        onTap: () => callBack(),
        child: Container(
          margin: const EdgeInsets.all(10),
          height: 50,
          width: 50,
          color: color,
          child: Center(
            child: Container(
              height: 20,
              width: 20,
              decoration: const BoxDecoration(
                shape: BoxShape.circle,
                color: Colors.white,
              ),
              child: Center(child: Text(text)),
            ),
          ),
        ),
      ),
    );
  }
}

这篇关于如何为连续2个项目的交换设置动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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