일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- set
- animation
- function
- Android
- python
- textstyle
- variable
- package
- pushnamed
- DART
- 클래스
- 콜렉션
- 함수
- crawler
- import
- map
- 다트
- List
- Collection
- 웹크롤러
- 코틀린
- 파이썬
- kotlin
- 플러터
- ML
- Flutter
- 크롤러
- Class
- texttheme
- text
- Today
- Total
조용한 담장
Flutter : Draggable 본문

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
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, | |
) |
로고를 움직이면 원래 있던 자리에는 회색의 아이콘이 그려지고, 드래그 되는 동안에는 원본과 동일한 위젯을 그리게 된다. 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, | |
)); | |
}, | |
) |
로고가 위로 드래그 되면 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, | |
)); | |
}, | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Reference
'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 |