Android-->ViewDragHelper的詳細使用方法
ViewDragHelper是Android系統原生封裝用於ViewGroup滑動的類庫.(ViewDragHelper只能用在ViewGroup中.)
使用ViewDragHelper,可以非常方便的在ViewGroup中移動,滑動任意一個子View,並且控制相當方便.
1:基礎程式碼模版
public class ViewDragTestLayout extends RelativeLayout {
ViewDragHelper mViewDragHelper;
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
//中間參數列示靈敏度,比如滑動了多少畫素才視為觸發了滑動.值越大越靈敏.
mViewDragHelper = ViewDragHelper.create(this, 1f, new DragCallback());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//固定寫法
int action = MotionEventCompat.getActionMasked(ev);
if (action == MotionEvent.ACTION_CANCEL
|| action == MotionEvent.ACTION_UP) {
mViewDragHelper.cancel();
return false;
}
return mViewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//固定寫法
mViewDragHelper.processTouchEvent(event);
return true;
}
@Override
public void computeScroll() {
//固定寫法
//此方法用於自動滾動,比如自動回滾到預設位置.
if (mViewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
}
以上程式碼,可以貼上複製. 都是模版程式碼;
2:ViewDragHelper.Callback
//這個類的回撥方法,才是ViewDragHelper的重點
private class ViewDragCallback extends ViewDragHelper.Callback{
@Override
public boolean tryCaptureView(View child, int pointerId) {
//child 表示想要滑動的view
//pointerId 表示觸控點的id, 比如多點按壓的那個id
//返回值表示,是否可以capture,也就是是否可以滑動.可以根據不同的child決定是否可以滑動
return true;
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//child 表示當前正在移動的view
//left 表示當前的view正要移動到左邊距為left的地方
//dx 表示和上一次滑動的距離間隔
//返回值就是child要移動的目標位置.可以通過控制返回值,從而控制child只能在ViewGroup的範圍中移動.
return left;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
//child 表示當前正在移動的view
//top 表示當前的view正要移動到上邊距為top的地方
//dx 表示和上一次滑動的距離間隔
return top;
}
}
重寫以上3個方法, 你的ViewGroup就可以正常工作了.子View就可以被任意拖動了.
3:控制child的移動範圍在父view中
//控制child只能在ViewGroup的橫向中移動
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mDragView.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}
//控制child只能在ViewGroup的縱向中移動
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
final int topBound = getPaddingTop();
final int bottomBound = getHeight() - mDragView.getHeight();
final int newTop = Math.min(Math.max(top, topBound), bottomBound);
return newTop;
}
回撥順序
//一次滑動週期的回撥順序.(開始拖動到放手)
getOrderedChildIndex - 0
getOrderedChildIndex - 0
tryCaptureView - tryCaptureView -1 0
onViewCaptured - null
onViewDragStateChanged - null
clampViewPositionHorizontal - left:11 dx:11
clampViewPositionVertical - top:5 dy:5
onViewPositionChanged - null
...
clampViewPositionHorizontal - left:100 dx:23
clampViewPositionVertical - top:44 dy:11
onViewPositionChanged - null
onViewReleased - null
onViewDragStateChanged - null
4:開啟邊界滑動
//開啟4個邊
mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_ALL);
//各個邊
public static final int EDGE_LEFT = 1 << 0;
public static final int EDGE_RIGHT = 1 << 1;
public static final int EDGE_TOP = 1 << 2;
public static final int EDGE_BOTTOM = 1 << 3;
//當開啟邊界滑動之後, 此方法就會回撥
@Override
public void onEdgeTouched(int edgeFlags, int pointerId) {
//通常開啟邊界之後, 都需要手動capture view.之後就可以滑動view了.
mViewDragHelper.captureChildView(getChildAt(1), pointerId);
}
@Override
public boolean tryCaptureView(View child, int pointerId) {
//開啟邊界之後, 這個方法的返回值可能需要進一步處理.要不然開邊界就沒啥意思了.
return false;
}
回撥順序:
getOrderedChildIndex - 2
onEdgeTouched - edgeFlags:4 pointerId:0
getOrderedChildIndex - 2
tryCaptureView - tryCaptureView -1 0
...
5:釋放後的回彈效果
有些時候, 當釋放的時候, 需要將View回到原來的位置.
//釋放的時候, 會回撥下面的方法
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
//呼叫這個方法,就可以設定releasedChild回彈得位置.
mViewDragHelper.settleCapturedViewAt(0, 100);//引數就是x,y的座標
postInvalidate();//注意一定要呼叫這個方法,否則沒效果.
}
//以下2個方法最終呼叫的都是forceSettleCapturedViewAt().
mViewDragHelper.settleCapturedViewAt(0, 100);
mViewDragHelper.smoothSlideViewTo(getChildAt(1), 0, 100);
//所以...發揮你的想象力,看看有什麼妙用!!!
//如果你還沒有忘記的話...前文應該有說過,涉及到scroll,需要重寫view的此方法.
//此方法一定要重寫,否則沒效果
@Override
public void computeScroll() {
//固定寫法
if (mViewDragHelper.continueSettling(true)) {
postInvalidate();//注意此處.
}
}
通過上面2個方法的設定, 當手指釋放的時候, View就會自動滑動到指定的位置...(不是一下子就到指定的位置哦,有一個滑動的過程.)
注意:如果需要滑動的View,會消耗touch事件,比如:Button,那麼需要重寫以下方法.
@Override
public int getViewHorizontalDragRange(View child) {
return child.getMeasuredWidth();//只要返回大於0的值就行
}
@Override
public int getViewVerticalDragRange(View child) {
return child.getMeasuredHeight();//只要返回大於0的值就行
}
到這裡, 就結束啦...
相關閱讀:
http://blog.csdn.net/lmj623565791/article/details/46858663
http://blog.csdn.net/pi9nc/article/details/39583377
至此: 文章就結束了,如有疑問: QQ群:274306954 歡迎您的加入.
相關文章
- NUnit2.0詳細使用方法
- 【轉】PHPmagic_quotes_gpc的詳細使用方法PHP
- PHP magic_quotes_gpc的詳細使用方法PHP
- vuex詳細介紹和使用方法Vue
- Android Handler詳細使用方法例項Android
- Linux 記憶體使用方法詳細解析Linux記憶體
- Linux系統下X終端的詳細使用方法Linux
- ViewDragHelper 的基本使用(一)View
- Linux系統下X終端的詳細使用方法(轉)Linux
- ViewDragHelper基本使用View
- 四,Java運算子詳細分類及使用方法介紹Java
- Python之pypmml:pypmml的簡介、安裝、使用方法之詳細攻略Python
- vlookup函式不會用?詳細使用方法就在這兒,用心學!函式
- 網路測試DOS命令詳細介紹及使用方法舉例
- 詳解 awk 工具的使用方法
- ViewDragHelper使用五步法View
- Python之selenium:selenium庫的簡介、安裝、使用方法之詳細攻略Python
- 12864點陣型液晶螢幕的基本原理與使用方法(很詳細)
- rman使用方法詳解
- Java File 類的使用方法詳解Java
- Android--下拉框Android
- Android--圖片集Android
- BASH命令使用方法詳解
- linux tail命令的使用方法詳解LinuxAI
- 詳述Linux ftp命令的使用方法LinuxFTP
- jquery 裡的each使用方法詳解薦jQuery
- Py之dlib:Python庫之dlib庫的簡介、安裝、使用方法詳細攻略Python
- android--執行緒池Android執行緒
- TF學習——TF之TensorFlow Slim:TensorFlow Slim的簡介、安裝、使用方法之詳細攻略
- Android ViewDragHelper 自定義 ViewGroup 神器AndroidView
- HashMap稍微詳細的理解HashMap
- 詳解MySQL中的SQRT函式的使用方法MySql函式
- FCKeditor使用方法技術詳解
- php中Session使用方法詳解PHPSession
- Android FragmentTabHost 使用方法詳解AndroidFragment
- 【機器學習科學庫】全md文件筆記:Matplotlib詳細使用方法(已分享,附程式碼)機器學習筆記
- Android--按鈕點選事件Android事件
- Android--自動搜尋提示Android