轉(zhuǎn)載注明出處:簡(jiǎn)書-十個(gè)雨點(diǎn)
簡(jiǎn)介
拖拽操作在現(xiàn)在的智能手機(jī)中并不少見,老羅的OneStep更是把拖拽做成了一種令人拍手叫絕的交互方式疟暖。在錘子手機(jī)原生的Bigbang中,普通拖動(dòng)是多選文字,長(zhǎng)按選中的文字并拖動(dòng)是觸發(fā)OneStep的分享功能胞皱。而我在模仿Bigbang的時(shí)候,覺得用戶可能需要對(duì)文字進(jìn)行一些微調(diào)九妈,所以我把長(zhǎng)按設(shè)計(jì)成了細(xì)分詞(把詞語細(xì)分成單字)反砌,而拖拽的交互留給了排序功能(需要切換排序開關(guān))。
效果圖
也可以下載全能分詞體驗(yàn)
實(shí)現(xiàn)原理和步驟
其實(shí)Android已經(jīng)提供了拖拽功能的接口宴树,在API level 11以上的View類中,直接調(diào)用startDrag()方法或者startDragAndDrop()即可晶疼。
渣翻一下:
public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder,
Object myLocalState, int flags)
開始一個(gè)拖拽操作酒贬。
調(diào)用這個(gè)方法時(shí)又憨,會(huì)將一個(gè)View.DragShadowBuilder對(duì)象傳遞給系統(tǒng)。
系統(tǒng)將調(diào)用這個(gè)View.DragShadowBuilder對(duì)象的onProvideShadowMetrics(Point, Point)方法來獲取拖拽陰影的metrics锭吨,
再調(diào)用其onDrawShadow(Canvas)方法來繪制拖拽陰影蠢莺。
之后,系統(tǒng)開始拖拽操作耐齐,并將拖拽事件(drag events)發(fā)送給你應(yīng)用中所有visible的View對(duì)象浪秘。
拖拽事件是被發(fā)送到View對(duì)象的drag listener或者onDragEvent()方法。
drag listener和onDragEvent()方法接收的參數(shù)都是一個(gè)DragEvent對(duì)象埠况,
對(duì)這個(gè)DragEvent對(duì)象執(zhí)行g(shù)etAction()方法的結(jié)果是ACTION_DRAG_STARTED耸携。
startDrag()方法可以在任何attacked的View對(duì)象上調(diào)用,
而不需要是View.DragShadowBuilder使用的View對(duì)象辕翰,也不需要與被拖拽的View有任何關(guān)系夺衍。
整個(gè)拖拽過程中涉及到的類只有三個(gè):ClipData,DragShadowBuilder和OnDragListener喜命,步驟只有如下兩步:
1. 設(shè)置拖拽數(shù)據(jù)沟沙,并開始拖拽
ClipData clipData = ClipData.newPlainText(lable, text);//這只是其中一種方式,還可以傳遞更豐富的數(shù)據(jù)
View.DragShadowBuilder myShadow = new DragShadowBuilder(view);
view.startDrag(clipData, myShadow, null, 0);
2. 在需要接收拖拽的View上設(shè)置監(jiān)聽
anotherView.setOnDragListener(new OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
doSomething();
return true;//true means consumed
}
});
看完上面的介紹是不是發(fā)現(xiàn)實(shí)現(xiàn)拖拽操作很簡(jiǎn)單呢壁榕?沒錯(cuò)矛紫,借助系統(tǒng)方法,我們需要做的工作極少牌里。
源碼
完整代碼參見Bigbang項(xiàng)目的BigBangLayout類的實(shí)現(xiàn)颊咬,拖拽的部分從initView()方法和onTouchEvent()方法看起即可。