Draggable小部件的反馈属性未设置动画

时间:2020-09-30 05:51:04

标签: flutter draggable flutter-animation

我需要为Draggable小部件移动时制作动画。动画取决于要拖动的小部件的全局位置坐标。我已经使用Listener来获取手指的轻敲位置,但是问题是feedback小部件的Draggable小部件未使用setState更新。我找到了thisthisthisthis链接,但是它们都没有帮助。 这是演示我的问题的代码。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  double x = 0, y = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Listener(
        onPointerMove: (opm) {
          setState(() {
            x = opm.position.dx;
            y = opm.position.dy;
          });
          print('(${x.floor()}, ${y.floor()})');
        },
        child: Center(
          child: Draggable(
            childWhenDragging: Container(),
            child: Container(
              height: 150,
              width: 150,
              color: Colors.red,
            ),
            feedback: Material(
              child: Container(
                height: 150,
                width: 150,
                color: Colors.blue,
                child: Center(child: Text('(${x.floor()}, ${y.floor()})')),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

在这种情况下,蓝屏内显示的坐标应设置动画,但即使执行setState也不会更新。我尝试使用AnimatedBuilder,但没有区别。如果有人可以通过Draggable小部件为我提供帮助或替代方法来实现此目的,那将非常有帮助。

1 个答案:

答案 0 :(得分:-1)

我对这部分内容不完全了解,但是在pskink的帮助下以及在一些文档的帮助下,我可以使用以下代码来实现此动画。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  double x = 0, y = 0;

  AnimationController _controller;

  Animation animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
    animation = Tween(begin: 0, end: 100).animate(_controller);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Listener(
        onPointerMove: (opm) {
          setState(() {
            x = opm.position.dx;
            y = opm.position.dy;
            _controller.value = 0;
          });
          print('(${x.floor()}, ${y.floor()})');
        },
        child: Center(
          child: Draggable(
            childWhenDragging: Container(),
            child: Container(
              height: 150,
              width: 150,
              color: Colors.red,
            ),
            feedback: AnimatedBuilder(
              animation: animation,
              builder: (_, __) {
                return Material(
                  child: Container(
                    height: 150,
                    width: 150,
                    color: Colors.blue,
                    child: Center(child: Text('(${x.floor()}, ${y.floor()})')),
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

如果您有更好的方法或想要添加一些其他信息或说明,请发表评论。