GestureDetectorを用いたドラッグ&ドロップの実装【Flutter】


Flutterでウィジェットのドラッグ&ドロップを実装するには通常、Draggableウィジェットでラップすると実現できる。
だが、例えば「グリッド線に沿ってドラッグ」などのギミックを作りたいときは不向きなのではないか?と思った。
(もしかするとDraggableでもできるかもしれないけど!わからん!)

そうして2日間GestureDetectorを利用したドラッグ&ドロップの方法を模索していたが、苦戦。
最終的にStack Overflowに質問をしてみたところ、秒速で解決したので、日本語でまとめておく。

ちなみにStack Overflowの記事はこちら。

コード

import 'package:flutter/material.dart';

class DragButton extends StatefulWidget {
  @override
  DragButtonState createState() => DragButtonState();
}

class DragButtonState extends State<DragButton> {
  Offset offset = new Offset(0.0, 0.0);

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: offset,
      child: GestureDetector(
        onPanUpdate: (DragUpdateDetails details) {
          setState(() {
            offset += details.delta;
          });
        },
        child: ElevatedButton(
          onPressed: null,
          child: Text('Button'),
        ),
      ),
    );
  }
}

こんな感じ。重要なのは下の部分。

        onPanUpdate: (DragUpdateDetails details) {
          setState(() {
            offset += details.delta;
          });
        },

details.deltaでドラッグの変化量を取得して、そのままoffsetに加算する感じ。
これで、自由にドラッグ&ドロップが実装できる!