본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[Android/안드로이드] Drag & Drop 에 대하여.

by 돼지왕 왕돼지 2012. 6. 8.
반응형

http://developer.android.com/guide/topics/ui/themes.html 

- Android API Level 11 ( HoneyComb ) 부터 적용된다.

- Drag 의 시작은 App.이 System에 drag 시작한다고 알리는 데부터. System 은 drag 할 
view 를 요구하며, drag event listener 를 통해서 app 에 상태를 전달한다. Drag 할 view drag shadow 라 불리는데, drag shadow 가 release 되면 drag 가 끝난다.


- View 에 setOnDragListener() 를 통해 listener 를 등록할 수도 있고, onDragEvent() callback 을 통해서도 event 를 전달받을 수 있다. 


- Drag 의 시작은 startDrag() 로 하며, 이 때 drag 하는 data 를 함께 보낸다.

 
- drag/drop 은 4가지 step 이 있다.

 1. Started : startDrag() 를 call 했을 때. 이 때 system 은 다시 drag shadow 를 요청하고, 받아가는 즉시 drag shadow 를 보여준다. 이 때 현재 Layout 에 있는 모든 View 에 ACTION_DRAG_STARTED 가 전달된다. 지속적으로 event 를 수렴하려면 true 를 return 해야만 하고, 반대로 더 이상 handle 하지 않아도 되는 문제라면 false 를 return 해주면 된다. true 를 return 한다는 것은 listener 를 등록하는 의미라고 보면 된다. false 를 return 한 경우에는 ACTION_DRAG_ENDED 가 발생할때까지는 추가 event 를 받지 못한다.


 2. Continuing : drag shadow 가 다른 view의 bounding box 를 touch 하게 되면 drag event listener 로 callback 이 전달됩니다. 전달되는 event는 ACTION_DRAG_ENTERED 이다. 보통 이 때 view 를 highlight 하는 행동을 한다. 


 3. Dropped : drag shadow 가 bounding box 안에서 releaase 한 경우. ACTION_DROP 이 전달된다. true 를 return 할 경우에는 drop event 를 성공적으로 처리했다는 의미이다. 이 drop event 는 listener 가 등록된 view 에 대해서만 전달된다. 


 4. Ended : ACTION_DRAG_ENDED 가 전달되며, 이 event 는 어디에서 release 하든 상관없이 전달이 된다. 


- ACTION_DRAG_ENTERED 를 받은 view 에서 계속해서 event 를 받으려면 true 를 return 해주어야 한다.





- ACTION_DRAG_LOCATION 는 ACTION_DRAG_ENTERED 를 받은 후에 계속해서 drag shadow 가 bounding box 안에 머문다면 이 event 를 받게 된다.


- ACTION_DRAG_EXITED 는 ACTION_DRAG_ENTERED 와 ACTION_DRAG_LOCATION 을 하나 이상 받은 다음에 drag shadow 가 해당 view 를 벗어나면 받게 되는 event이다.


- ACTION_DRAG_ENDED event 에 대해 getResult() 를 하여 ACTION_DRAG_DROP 이 제대로 처리되었는지 알 수 있다.


- drag shadow 는 DragShadowBuilder 를 통해서 만들고, startDrag() 에 parameter 로 전달한다. DragShadow 에는 2가는 constructor 가 있는데 parameter 가 없는 녀석과 view를 parameter 로 받는 녀석이 있다. paramter 가 없는 녀석은 view 가 없는 shadow 가 되며 이것을 에러가 아니다.


- DragShadowBuilder 에는 2개의 함수가 있다. 

onProvideShadowMetrics() 는 startDrag 를 호출하면서 바로 불리는데, 이녀석을 통해서 drag shadow 의 dimension 과 touch point 를 명시한다. dimension 은 Point object 로 width 가 x값에 height 가 y값에 들어간다. touch_point 도 Point object 로 drag shadow 가 손가락에 위치할 point 를 명시한다. 

onDrawShadow() 함수는 onProvideShadowMetrics() 후에 바로 불리는데, Canvas 가 argument 로 들어오고, 이녀석에 draw 를 한 것이 shadow 가 된다.


- performance 를 위해서 drag shadow 는 작은 것이 좋다. 만약 multiple item 을 drag 한다면, 멀리 펼쳐져 있는 녀석을 캡춰해서 사용하기보다는 stack 모양으로 쌓아서 함께 이동하여 크기를 줄이는 것이 좋다.


- ClipData 와 ClipData.Item 은 meta data 를 담는 곳이다. 만약 meta data 가 필요없다면 null 을 전달하면 된다.


- ACTION_DRAG_STARTED event 를 받으면 보통 getClipDescription() 을 통해 해당 view 가 이녀석의 drag & drop 에 관여할것인지를 판단하여, 관여하려면 true 를 아니면 false 를 return 하면 된다. false 를 return 한 경우에는 해당 drag & drop 의 sequence 에 대한 ACTION_DRAG_ENDED 가 불리기 전까지 event 를 받지 않는다. ACTION_DRAG_STARTED 에서는 getClipData(), getX(), getY(), getResult() 는 유효하지 않는다.





- ACTION_DROP 이 들어오면 getClipData() 를 통해 ClipData 를 가져오고, 해당 callback 에서 event 를 consume 할 경우에는 true 를 return 해준다. System 이 ACTION_DROP 을 전달하지 않는 경우도 있는데 이 경우에 getResult() 는 false 이다. ACTION_DROP 이 전달되지 않는 point 는 intersect 된 view 가 없거나, 해당 application 바깓쪽에 drop 되거나 등의 경우이다.


- ACTION_DROP event 시 getX(), getY() 는 drop 을 받는 view 에서의 x, y 위치이다.


- ACTION_DRAG_ENDED 는 ACTION_DROP 후에 모든 listener 에게 전달이 된다. 이 event 에서는 보통 이전 event 에서 바꿨던 drag shadow 의 view 를 원복시키고, ACTION_DROP 의 처리결과에 대한 후처리를 해준다. listener 는 true 를 return 해주어야 한다.







반응형

댓글