はじめに
Flutterを触ってるみなさんこんにちは、名無しさんです。
今回は、Draggableについて色々と知見をまとめてみましたので備忘録としておいて行こうかなと思います。
Draggableについて
今回取り扱うDraggableについて
公式のリファレンスをDeeplさんで翻訳をかけると
ドラッグ可能なウィジェットは、ドラッグ・ジェスチャーの開始を認識すると、ユーザの指を画面上で追跡するフィードバック・ウィジェットを表示します。 ユーザが DragTarget の上で指を離すと、その DragTarget は Dragable によって運ばれたデータを受け入れる機会を与えられます。
とのように要約するとドラック&ドラッグを実装するウィジェットです
簡単に公式のサンプルコードを動かしてみましょう。
公式サンプルコード
import 'package:flutter/material.dart';
/// Flutter code sample for [Draggable].
void main() => runApp(const DraggableExampleApp());
class DraggableExampleApp extends StatelessWidget {
const DraggableExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Draggable Sample')),
body: const DraggableExample(),
),
);
}
}
class DraggableExample extends StatefulWidget {
const DraggableExample({super.key});
@override
State<DraggableExample> createState() => _DraggableExampleState();
}
class _DraggableExampleState extends State<DraggableExample> {
int acceptedData = 0;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Draggable<int>(
// Data is the value this Draggable stores.
data: 10,
feedback: Container(
color: Colors.deepOrange,
height: 100,
width: 100,
child: const Icon(Icons.directions_run),
),
childWhenDragging: Container(
height: 100.0,
width: 100.0,
color: Colors.pinkAccent,
child: const Center(
child: Text('Child When Dragging'),
),
),
child: Container(
height: 100.0,
width: 100.0,
color: Colors.lightGreenAccent,
child: const Center(
child: Text('Draggable'),
),
),
),
DragTarget<int>(
builder: (
BuildContext context,
List<dynamic> accepted,
List<dynamic> rejected,
) {
return Container(
height: 100.0,
width: 100.0,
color: Colors.cyan,
child: Center(
child: Text('Value is updated to: $acceptedData'),
),
);
},
onAcceptWithDetails: (DragTargetDetails<int> details) {
setState(() {
acceptedData += details.data;
});
},
),
],
);
}
}
今回のコードをより詳しく見ていきましょう。
body
の部分から
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Draggable<int>(
この部分では横に並べるでおなじみのrow
のchildreとしてDraggableを定義して言います。
ここはよくあるウィジェットのツリー構造と同じですよね。
横に並んでますね。
Draggable
ここからが大事です。
Draggable<int>( // ①
data: 10, // ②
feedback: Container( //③
color: Colors.deepOrange,
height: 100,
width: 100,
child: const Icon(Icons.directions_run),
),
この部分について
まず①について
Draggable
はウィジェット名です。ここに色々と引数として値を持たせていきます。
data
→ドラッガブルによってドロップされるデータになります。
今回の場合10をドロップすることになります。
feedback
→ドラック中に表示しておくウィジェットです。
実行例①
feedback
で定義した処理は
オレンジになっている部分
data
で定義された処理は青くなっている部分が10追加されている部分
childWhenDragging: Container( // ①
height: 100.0,
width: 100.0,
color: Colors.pinkAccent,
child: const Center(
child: Text('Child When Dragging'),
),
),
①について
childWhenDragging
→一つのウィジェットがドラック中に(浮いている時)に子ウィジェットとして表示するところ
実行例
『Child When Dragging』が今回定義した部分
DragTarget
このウィジェットはドラッガブルウィジェットを受け取る仕事をするウェイジェットです。
少しコード例だけでは分かりにくいので骨組みを見ながら解説していきます。
DragTarget<int>(builder: (BuildContext context,List<dynamic> accepted,List<dynamic> rejected,)
まず最初の引数の部分です。
DragTargetは今回、引数として2つの要素を持っています。
builder
onAcceptWithDetails
※onAccept
がv3.14.0-0.2以降非推奨となり公式よりonAcceptWithDetails
を使うほうがいいとのことです(ドラッグの詳細が提供できないためらしい)
引数を確認していきます。
builder
-
BuildContext context,List<dynamic>
→ よくある画面の状態をウィジェットに引き渡しています。 -
accepted,List<dynamic>
→ ドラックされたアイテムのデータ配列 -
rejected,
→ドラックされたアイテムのデータ
という構造になっています。
参考記事