Animation 如何在flatter中设置交换小部件的动画?

Animation 如何在flatter中设置交换小部件的动画?,animation,flutter,dart,Animation,Flutter,Dart,我正试图让我的头周围实现下面的设计在颤振。 该设计由两个文本小部件和一个交换图标组成,单击该图标,两个文本小部件将动态地交换位置。我试着堆叠和定位,但我无法得到它 您可以使用堆栈和定位交换两个小部件,最终添加动画效果。我举两个例子: 第一个代码只是交换两个小部件。 第二个代码示例添加动画效果 交换两个小部件(无动画) 导入“包装:颤振/材料.省道”; void main(){ runApp(MyApp()); } 类MyApp扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返回材料PP

我正试图让我的头周围实现下面的设计在颤振。 该设计由两个文本小部件和一个交换图标组成,单击该图标,两个文本小部件将动态地交换位置。我试着堆叠和定位,但我无法得到它


您可以使用堆栈和定位交换两个小部件,最终添加动画效果。我举两个例子: 第一个代码只是交换两个小部件。 第二个代码示例添加动画效果

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

导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:ThemeData.dark(),
debugShowCheckedModeBanner:false,
家:脚手架(
正文:中(
子项:MyWidget(),
),
),
);
}
}
类MyWidget扩展了StatefulWidget{
@凌驾
createState()=>\u MyWidgetState();
}
类_MyWidgetState扩展状态{
最终双地址1top=20;
最终双地址2top=110;
布尔交换=假;
@凌驾
小部件构建(构建上下文){
返回容器(
宽度:300,
身高:150,
颜色:颜色,蓝色,
子:堆栈(
儿童:[
//最高地址
定位(
顶部:交换?地址2顶部:地址1顶部,
左:20,,
child:Text(“这是第一个地址”),
),
//底部地址
定位(
顶部:交换?地址1顶部:地址2顶部,
左:20,,
子:文本(“这是另一个地址”),
),
//交换按钮
定位(
前50名,
右:20,,
孩子:扁平按钮(
按下时:()=>设置状态(){
交换=!交换;
}),
子项:文本(“交换”),
),
),
],
),
);
}
}
用动画交换两个小部件

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"),
            ),
          ),
        ],
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:ThemeData.dark(),
debugShowCheckedModeBanner:false,
家:脚手架(
正文:中(
子项:MyWidget(),
),
),
);
}
}
类MyWidget扩展了StatefulWidget{
@凌驾
createState()=>\u MyWidgetState();
}
类_MyWidgetState使用TickerProviderStateMixin扩展状态{
最终双地址1top=20;
最终双地址2top=110;
布尔交换=假;
动画;
动画控制器;
animationListener()=>setState((){});
@凌驾
void didChangeDependencies()异步{
super.didChangeDependencies();
//初始化动画
controller=AnimationController(持续时间:const持续时间(毫秒:300),vsync:this);
addressAnimation=Tween(开始:0.0,结束:address2Top-address1Top).animate(曲线动画(父对象:控制器,曲线:常量间隔(0.0,1.0,曲线:Curves.easeInOut))…addListener(animationListener);
}
@凌驾
处置{
//处理动画控制器
controller.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
var tweenValue=addressAnimation?.value±0.0;
返回容器(
宽度:300,
身高:150,
颜色:颜色,蓝色,
子:堆栈(
儿童:[
//最高地址
定位(
顶部:address1Top+tweenValue,
左:20,,
child:Text(“这是第一个地址”),
),
//底部地址
定位(
顶部:address2Top-tweenValue,
左:20,,
子:文本(“这是另一个地址”),
),
//交换按钮
定位(
前50名,
右:20,,
孩子:扁平按钮(
按下时:()=>设置状态(){
交换?controller.reverse():controller.forward();
交换=!交换;
}),
子项:文本(“交换”),
),
),
],
),
);
}
}

希望这对您有所帮助:)

您不需要交换小部件,如果您不需要任何动画,您可以交换实际文本,您可以询问如何交换处于其位置的小部件,或者如何为正在交换的小部件设置动画?两个不同的问题。更新了问题。寻找更改两个widgetsWill的动画效果,请尝试并更新