Flutter 跟随手指移动的Widget, 自动贴边

1,479 阅读1分钟

查了一下网上没有。然后把自己选的悬窗widget中的可移动widget分享一下。

height 这个参数是widget 默认的y轴的位置 child 这个参数是要显示的widget。

父容器记得要是Stack。否则无法移动


class MoveWidget extends StatefulWidget {
  final Widget child;
  final double height;

  const MoveWidget({Key key, this.child, this.height}) : super(key: key);

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

class _MoveWidgetState extends State<MoveWidget> {
  double _bottom = 0.0;
  double _left = 0.0;
  double _right;

  @override
  void initState() {
    _bottom = widget.height;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        left: _left,
        right: _right,
        bottom:_bottom,
        child: Material(
          color: Colors.transparent,
          child: GestureDetector(
            onPanUpdate: (e) {
              setState(() {
                if(_left !=null){
                  _left = _left + e.delta.dx;
                }else{
                  _right = _right-e.delta.dx;
                }
                _bottom = _bottom - e.delta.dy;
              });
            },
            onPanEnd: (DragEndDetails details){
              setState(() {
                if(_left !=null){
                  if(_left>MediaQuery.of(context).size.width/2){
                    _left = null;
                    _right = 0;
                  }else{
                    _left = 0;
                    _right =null;
                  }

                }else{
                  if(_right<MediaQuery.of(context).size.width/2){
                    _left = null;
                    _right = 0;
                  }else{
                    _left = 0;
                    _right =null;
                  }
                }
                if(_bottom <MediaQuery.of(context).padding.bottom){
                  _bottom = MediaQuery.of(context).padding.bottom;
                }

              });

            },
            child: widget.child ??
                Container(
                  width: 100,
                  height: 100,
                  color: Colors.red,
                  child: Center(child: Text('没有添加任何视图')),
                ),
          ),
        ));
  }
}