조용한 담장

Flutter : Draggable 본문

Flutter

Flutter : Draggable

iosroid 2019. 10. 28. 16:16

Draggable

위젯을 드래그 하여 움직일 수 있게 해보자.

Draggable class

Draggable({Key key, @required Widget child, @required Widget feedback, T data, Axis axis, Widget childWhenDragging, Offset feedbackOffset: Offset.zero, DragAnchor dragAnchor: DragAnchor.child, Axis affinity, int maxSimultaneousDrags, VoidCallback onDragStarted, DraggableCanceledCallback onDraggableCanceled, DragEndCallback onDragEnd, VoidCallback onDragCompleted, bool ignoringFeedbackSemantics: true })

A widget that can be dragged from to a DragTarget.

위젯을 드래그 할 수 있도록 만들어주며 드래그 관련 동작을 처리할 수 있게 해준다.

child 는 드래그 할 대상이 되는 위젯이다.

feedback 은 드래그 되는 동안 터치 포인트 위치에 그려질 위젯이다.

childWhenDragging 은 드래그가 시작되면 움직일 위젯의 원래 위치에 그려질 위젯이다.

data 는 드래그가 완료되어 DragTarget 에 드롭될 때 전달할 데이터 이다.

콜백들을 통해 동작들을 구현한다.

DragTarget class

DragTarget({Key key, @required DragTargetBuilder builder, DragTargetWillAccept onWillAccept, DragTargetAccept onAccept, DragTargetLeave onLeave })

A widget that receives data when a Draggable widget is dropped.

드래그 된 위젯이 드롭할 대상이 되는 위젯이다.

드래그 된 위젯이 드롭 이 위젯 위에서 드롭되면 전달되는 데이터 값을 사용할지를 콜백을 통해 결정할 수 있다.

Example

가운데 있는 두개의 로고를 위 아래에 있는 노란색 아이콘에 드래그 하여 Draggable 의 동작을 확인해 볼 수 있다.

노란색 아이콘은 각각 DragTarget 위젯이 되고 두개의 Flutter logo 는 Draggable 위젯이 된다.

Draggable Widgets

Draggable(
child: FlutterLogo(size: 50.0, colors: Colors.red,),
feedback: FlutterLogo(size: 50.0, colors: Colors.red,),
childWhenDragging: FlutterLogo(colors: Colors.blueGrey, size: 50.0,),
data: FlutterLogoColor.red,
)
view raw draggable1.dart hosted with ❤ by GitHub

로고를 움직이면 원래 있던 자리에는 회색의 아이콘이 그려지고, 드래그 되는 동안에는 원본과 동일한 위젯을 그리게 된다. DragTarget 에 드롭되면 FlutterLogoColor.red 값을 전달한다.

DragTarget Widgets

DragTarget(
builder: (context, List<FlutterLogoColor> candidateData, rejectedData) {
return Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
color: Colors.yellow[600],
shape: BoxShape.circle
),
child: Icon(Icons.delete, size: 40, color: Colors.white70,),
);
},
onWillAccept: (data) {
if (data == FlutterLogoColor.red) {
return true;
} else {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text("Not Allowed!"),
duration: Duration(seconds: 1),
));
return false;
}
},
onAccept: (data) {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text("Deleted!"),
duration: Duration(seconds: 1),
backgroundColor: Colors.red,
));
},
)
view raw draggable2.dart hosted with ❤ by GitHub

로고가 위로 드래그 되면 onWillAccept 콜백으로 데이터가 전달되고 빨간색 로고값인 경우 true 를 리턴하면 onAccept 이 콜되여 처리하게 된다.

onWillAccept 에서 false 가 리턴되면 해당 드래그의 데이터는 거부되어 onAccept 가 콜되지 않는다.

enum FlutterLogoColor { red, blue }
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// ...
home: MyHomePage(title: 'Draggable Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
// ...
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: DragTarget(
builder: (context, List<FlutterLogoColor> candidateData, rejectedData) {
return Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
color: Colors.yellow[600],
shape: BoxShape.circle
),
child: Icon(Icons.delete, size: 40, color: Colors.white70,),
);
},
onWillAccept: (data) {
if (data == FlutterLogoColor.red) {
return true;
} else {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text("Not Allowed!"),
duration: Duration(seconds: 1),
));
return false;
}
},
onAccept: (data) {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text("Deleted!"),
duration: Duration(seconds: 1),
backgroundColor: Colors.red,
));
},
),
),
Container(
height: 100.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Draggable(
child: FlutterLogo(size: 50.0, colors: Colors.red,),
feedback: FlutterLogo(size: 50.0, colors: Colors.red,),
childWhenDragging: FlutterLogo(colors: Colors.blueGrey, size: 50.0,),
data: FlutterLogoColor.red,
),
Draggable(
child: FlutterLogo(size: 50.0,),
feedback: FlutterLogo(size: 50.0,),
childWhenDragging: FlutterLogo(colors: Colors.blueGrey, size: 50.0,),
data: FlutterLogoColor.blue,
),
],
),
Container(
height: 100.0,
),
Container(
child: DragTarget(
builder: (context, List<FlutterLogoColor> candidateData, rejectedData) {
return Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
color: Colors.yellow[600],
shape: BoxShape.circle
),
child: Icon(Icons.move_to_inbox, size: 40, color: Colors.white70,),
);
},
onWillAccept: (data) {
return true;
},
onAccept: (data) {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text("Archived!"),
duration: Duration(seconds: 1),
backgroundColor: data==FlutterLogoColor.blue?Colors.lightBlue:Colors.red,
));
},
),
),
],
),
),
);
}
}
view raw draggable3.dart hosted with ❤ by GitHub

Reference

Flutter Documentation

'Flutter' 카테고리의 다른 글

Flutter : permission_handler  (0) 2019.11.05
Flutter : DataTable  (3) 2019.11.04
Flutter : SelectableText  (0) 2019.10.21
Flutter : Navigator  (0) 2019.10.17
Flutter : Text Widgets  (0) 2019.10.14
Comments