ViewDragHelper的使用

聲明:非原創(chuàng)

ViewDragHelper是什么

viewDragHelper是寫自定義ViewGroups的工具類季研,對于用戶處理views在它的父容器里面的拖動以及相對應(yīng)的響應(yīng)弱左,它提供了豐富有用的操作和狀態(tài)跟蹤的API

ViewDragHelper創(chuàng)建

image
  1. Viewgroup——與 ViewDragHelper 相關(guān)聯(lián)的 ViewGroup蚕冬。
  2. ViewDragHelper.Callback cb ——ViewDragHelper.Callback 是個回調(diào)

ViewDragHelper.Callback

ViewDragHelper 提供了一系列回調(diào)誊抛,一下是全部回調(diào)

// 控制橫軸的移動距離 
int clampViewPositionHorizontal(View child, int left, int dx)
//控制縱軸的移動距離 
int clampViewPositionVertical(View child, int top, int dy)
// 獲取子視圖的Z值
int getOrderedChildIndex(int index)
//獲取視圖在橫軸移動的距離 
int getViewHorizontalDragRange(View child)
//獲取視圖在縱軸移動的距離 
int getViewVerticalDragRange(View child)
//處理當(dāng)用戶觸碰邊界移動開始的回調(diào) 
void    onEdgeDragStarted(int edgeFlags, int pointerId)
//處理邊界被鎖定時的回調(diào) 
boolean onEdgeLock(int edgeFlags)
//處理邊界被觸碰時的回調(diào) 
void    onEdgeTouched(int edgeFlags, int pointerId)
//當(dāng)視圖被捕獲時的回調(diào) 
void    onViewCaptured(View capturedChild, int activePointerId)
//當(dāng)視圖的拖動狀態(tài)改變的時候的回調(diào) 
void    onViewDragStateChanged(int state)
//當(dāng)捕獲的視圖位置發(fā)生改變的時候的回調(diào) 
void    onViewPositionChanged(View changedView, int left, int top, int dx, int dy)
//當(dāng)視圖的拖動被釋放的時候的回調(diào) 
void    onViewReleased(View releasedChild, float xvel, float yvel)
// 判斷此時的視圖是否為想要捕獲的視圖時會調(diào)用 
abstract boolean    tryCaptureView(View child, int pointerId)

作為初學(xué)者,我們要用最少的代碼把ViewDragHelper創(chuàng)建出來

ViewDragHelper 用哪幾個回調(diào)能構(gòu)成最簡單能運(yùn)行的實(shí)例呢锥债?

// 決定了是否需要捕獲這個 child,只有捕獲了才能進(jìn)行下面的拖拽行為
abstract boolean    tryCaptureView(View child, int pointerId)  


// 修整 child 水平方向上的坐標(biāo)践樱,left 指 child 要移動到的坐標(biāo),dx 相對上次的偏移量
int clampViewPositionHorizontal(View child, int left, int dx)

// 修整 child 垂直方向上的坐標(biāo)凸丸,top 指 child 要移動到的坐標(biāo)拷邢,dy 相對上次的偏移量
int clampViewPositionVertical(View child, int top, int dy)


// 手指釋放時的回調(diào)
void    onViewReleased(View releasedChild, float xvel, float yvel)

ViewDragHelper使用

拖拽的相關(guān)方法

/** 是否應(yīng)該攔截 children 的觸摸事件,
*只有攔截了 ViewDragHelper 才能進(jìn)行后續(xù)的動作
*
*將它放在 ViewGroup 中的 onInterceptTouchEvent() 方法中就好了
**/
boolean shouldInterceptTouchEvent(MotionEvent ev)

/** 處理 ViewGroup 中傳遞過來的觸摸事件序列
*在 ViewGroup 中的 onTouchEvent() 方法中處理
*/
void    processTouchEvent(MotionEvent ev)

拖拽后回彈

相關(guān)方法

//將 child 安置到坐標(biāo) (final Left,final Top) 的位置甲雅。
settleCapturedViewAt(int finalLeft, int finalTop)
// 在此方法中記錄拖拽前的坐標(biāo)
void onViewCaptured(View capturedChild, int activePointerId)

思路:

  1. 在 onViewCaptured() 方法中 或者 viewgroup的onLayout() 記錄拖拽前的坐標(biāo)解孙。
  2. 在 onViewReleased() 方法中調(diào)用 settleCapturedViewAt() 方法來重定位 child。

邊緣觸發(fā)

相關(guān)API

//處理當(dāng)用戶觸碰邊界移動開始的回調(diào) 
void    onEdgeDragStarted(int edgeFlags, int pointerId)
//處理邊界被鎖定時的回調(diào) 
boolean onEdgeLock(int edgeFlags)
//處理邊界被觸碰時的回調(diào) 
void    onEdgeTouched(int edgeFlags, int pointerId)

思路

  1. tryCaptureView 返回true使得view可以被捕獲
  2. onEdgeDragStarted 中使用 captureChildView 捕獲特定的view
  3. mDragHelper.setEdgeTrackingEnabled() 設(shè)置邊緣出發(fā)

移動button

因?yàn)?Button 本身能夠響應(yīng)點(diǎn)擊事件抛人,那么 ViewDragHelper 移動button需要特殊處理

這兩個方法只要返回值大于 0 疲陕,那么它就可以滑動胯努。

@Override
public int getViewHorizontalDragRange(View child) {
?    return 1;
}

@Override
public int getViewVerticalDragRange(View child) {
?    return 1;
}

注意

  1. tryCaptureView() 方法返回 true 時才會導(dǎo)致下面的回調(diào)方法被調(diào)用
  2. 邊緣觸發(fā)的邊緣指的是 這個viewgroup的邊緣步悠,而非屏幕的邊緣

源碼

參考

  1. http://blog.csdn.net/briblue/article/details/73730386#t7
  2. http://blog.csdn.net/lmj623565791/article/details/46858663
  3. http://blog.csdn.net/lepaitianshi/article/details/50961596
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钉跷,一起剝皮案震驚了整個濱河市伞访,隨后出現(xiàn)的幾起案子杆烁,更是在濱河造成了極大的恐慌民泵,老刑警劉巖皆撩,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寂恬,死亡現(xiàn)場離奇詭異续誉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)初肉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門酷鸦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人牙咏,你說我怎么就攤上這事臼隔。” “怎么了妄壶?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵摔握,是天一觀的道長。 經(jīng)常有香客問我丁寄,道長氨淌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任伊磺,我火速辦了婚禮盛正,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奢浑。我一直安慰自己蛮艰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著壤蚜,像睡著了一般即寡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上袜刷,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天聪富,我揣著相機(jī)與錄音,去河邊找鬼著蟹。 笑死墩蔓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的萧豆。 我是一名探鬼主播奸披,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涮雷!你這毒婦竟也來了阵面?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洪鸭,失蹤者是張志新(化名)和其女友劉穎样刷,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體览爵,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡置鼻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜓竹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箕母。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖梅肤,靈堂內(nèi)的尸體忽然破棺而出司蔬,到底是詐尸還是另有隱情,我是刑警寧澤姨蝴,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布俊啼,位于F島的核電站,受9級特大地震影響左医,放射性物質(zhì)發(fā)生泄漏授帕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一浮梢、第九天 我趴在偏房一處隱蔽的房頂上張望跛十。 院中可真熱鬧,春花似錦秕硝、人聲如沸芥映。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奈偏。三九已至坞嘀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惊来,已是汗流浹背丽涩。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裁蚁,地道東北人矢渊。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像枉证,于是被迫代替她去往敵國和親矮男。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容