Android ViewDragHelper使用方法詳解
幫我們實現(xiàn)各種類型的復雜手勢操作。其實例通過靜態(tài)工廠創(chuàng)建ViewDragHelper一般用在一個自定義ViewGroup的內(nèi)部。
初始化操作
private ViewDragHelper mDrragHelper; public SlideViewGroup(@NonNull Context context) { this(context,null); } public SlideViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public SlideViewGroup(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); mDrragHelper=ViewDragHelper.create(this,1.0f,mCallback); }
mDrragHelper=ViewDragHelper.create(this,1.0f,mCallback);第一個操作表示當前操作的對象,第二個參數(shù)為手勢操作敏感度,
第三個參數(shù)為我們手勢處理的毀掉接口
我們需要先在view事件分發(fā)時把手勢操作交給ViewFragHelper
@Override public boolean onInterceptTouchEvent(MotionEvent event) { //交給viewdrag去攔截 //事件分發(fā)攔截 float x=0; int action = event.getAction(); switch(action){ case MotionEvent.ACTION_DOWN: x =event.getX(); break; // return false; case MotionEvent.ACTION_MOVE: if (STATE==0&getX()-x<0){ return mDrragHelper.shouldInterceptTouchEvent(event); }else if (STATE==1){ return mDrragHelper.shouldInterceptTouchEvent(event); } break; } return false; } //boolean control=true;//控制downx的初始化 @Override public boolean onTouchEvent(MotionEvent event) { mDrragHelper.processTouchEvent(event); //if (control) float downX=0; if (event.getAction()==MotionEvent.ACTION_DOWN){ downX=event.getRawX(); if (STATE==1){ //if (event.getRawX()>0&downX<leftWidth-rightViewWidth) //close(); // Toast.makeText(this.getContext(), "leftWidth"+leftWidth+"rawx"+event.getRawX(), Toast.LENGTH_SHORT).show(); } } if (event.getAction()==MotionEvent.ACTION_UP){ //Toast.makeText(this.getContext(), "downx"+downX, Toast.LENGTH_SHORT).show(); //點擊刪除//&downX>leftWidth-rightViewWidth&downX<leftWidth-rightViewWidth/2 // Toast.makeText(this.getContext(), "刪除1", Toast.LENGTH_SHORT).show(); if (STATE==1&event.getRawX()>leftWidth-rightViewWidth&event.getRawX()<leftWidth-rightViewWidth/2){ // Toast.makeText(this.getContext(), "刪除2", Toast.LENGTH_SHORT).show(); if (skipListener!=null){ // Toast.makeText(this.getContext(), "刪除3", Toast.LENGTH_SHORT).show(); skipListener.onDelete(); } // Toast.makeText(this.getContext(), "刪除", Toast.LENGTH_SHORT).show(); } //點擊刪除&downX>leftWidth-rightViewWidth/2&downX<leftWidth-rightViewWidth if (STATE==1&event.getRawX()>leftWidth-rightViewWidth/2&event.getRawX()<leftWidth){ // Toast.makeText(this.getContext(), "修改", Toast.LENGTH_SHORT).show(); if (skipListener!=null){ skipListener.onDefine(); } } } return true; }
重點在這兩句
mDrragHelper.shouldInterceptTouchEvent(event); mDrragHelper.processTouchEvent(event);
我們可以在onInterceptTouchEvent決定什么時候把事件交給我們的手勢操作類
然后是回調(diào)類
private ViewDragHelper.Callback mCallback=new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return child==leftView; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { if (left>=0) return 0; if (left<-rightViewWidth) return -rightViewWidth; return left; } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { super.onViewPositionChanged(changedView, left, top, dx, dy); rightView.layout(leftWidth + left, 0, leftWidth + rightViewWidth, viewHeight); /* if (left<0&left>rightViewWidth/2){ mDrragHelper.smoothSlideViewTo(leftView,left,0); mDrragHelper.smoothSlideViewTo(rightView,left,0); }*/ /* if (left>=-(leftWidth+rightViewWidth)) { rightView.layout(leftWidth + left, 0, leftWidth + rightViewWidth, viewHeight); } if (left<-(leftWidth+rightViewWidth)){ rightView.layout(leftWidth, 0, leftWidth + rightViewWidth, viewHeight); }*/ } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); Log.i("left xvel",xvel+"y"+yvel); if (xvel<0){ open();/* mDrragHelper.smoothSlideViewTo(rightView,rightViewWidth/2,0);*/ }else if (leftView.getLeft()<-rightViewWidth/2) {open();}else { // Log.i("left open","open"); close(); } } @Override public int getViewHorizontalDragRange(View child) { return -rightViewWidth; } @Override public void onEdgeTouched(int edgeFlags, int pointerId) { super.onEdgeTouched(edgeFlags, pointerId); } };
tryCaptureView的返回值表示我們允許操作的child
clampViewPositionHorizontal()方法的默認返回值為0,返回值代表水平移動的距離,也就是left值,當返回left值時,我們操作的view就會跟著我們的拖動而移動,當然還有數(shù)值方向的方法,如果需要也可以重寫豎直操作的方法
onViewPositionChanged()方法就是當我們移動時就會回調(diào)這個方法,此處的left參數(shù)就是水平移動返回的left,dx就是水平距離相對變化
onViewRelased()方法就是手指抬起時(釋放)時回調(diào)的方法,xvel每秒鐘水平速度速度慢時為0,單位為像素,yvel為每秒鐘豎直方向的速度。速度有正負之分
滑動邊緣:
分為滑動左邊緣還是右邊緣:EDGE_LEFT和EDGE_RIGHT,下面的代碼設(shè)置了可以處理滑動左邊緣:
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
假如如上設(shè)置,onEdgeTouched方法會在左邊緣滑動的時候被調(diào)用,這種情況下一般都是沒有和子view接觸的情況。
@Override public void onEdgeTouched(int edgeFlags, int pointerId) { super.onEdgeTouched(edgeFlags, pointerId); Toast.makeText(getContext(), "edgeTouched", Toast.LENGTH_SHORT).show(); }
如果你想在邊緣滑動的時候根據(jù)滑動距離移動一個子view,可以通過實現(xiàn)onEdgeDragStarted方法,并在onEdgeDragStarted方法中手動指定要移動的子View
@Override public void onEdgeDragStarted(int edgeFlags, int pointerId) { mDragHelper.captureChildView(mDragView2, pointerId); }
滑動
手指在當前view的下邊緣就可以滑動
下面看一個我在ontochEvent調(diào)用的方法
public void open(){ if (listener!=null){ listener.onOpen(this); } if (mDrragHelper.smoothSlideViewTo(leftView,-rightViewWidth,0)) ViewCompat.postInvalidateOnAnimation(SlideViewGroup.this); STATE=1; }
就是平滑滑動,
ViewCompat.postInvalidateOnAnimation(SlideViewGroup.this)
上面那個方法就是刷新布局(重繪操作)
然后會回調(diào)次viewgroup的computerScroll
@Override public void computeScroll() { if (mDrragHelper.continueSettling(true)) { ViewCompat.postInvalidateOnAnimation(this); } }
其實滑動本身還是調(diào)用的scrollto跟據(jù)時間百分比移動,根據(jù)比例移動固定距離后就不移動了,所以我們需要重復刷新,需要判斷臨界條件,可能是時間可能是距離,可以點進continueSetting方法返回false代表動畫完成,進去一看就明白了,需要判斷滑動事件是否完成,如果完成就不再刷新,如果沒完成就刷新。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Android利用ViewDragHelper輕松實現(xiàn)拼圖游戲的示例
- Android ViewDragHelper仿淘寶拖動加載效果
- Android ViewDragHelper使用介紹
- Android 中通過ViewDragHelper實現(xiàn)ListView的Item的側(cè)拉劃出效果
- Android ViewDragHelper完全解析 自定義ViewGroup神器
- Android基于ViewDragHelper仿QQ5.0側(cè)滑界面效果
- Android使用ViewDragHelper實現(xiàn)仿QQ6.0側(cè)滑界面(一)
- Android使用ViewDragHelper實現(xiàn)QQ6.X最新版本側(cè)滑界面效果實例代碼
相關(guān)文章
Android SharedPreferences實現(xiàn)記住密碼和自動登錄
這篇文章主要為大家詳細介紹了Android SharedPreferences實現(xiàn)記住密碼和自動登錄,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05詳解如何在Flutter中用小部件創(chuàng)建響應式布局
由于Flutter的跨平臺、單一代碼庫的能力,了解屏幕管理以防止像柔性溢出錯誤或糟糕的用戶界面設(shè)計這樣的問題是至關(guān)重要的。本文將探討如何用靈活和擴展的小部件創(chuàng)建響應式布局,需要的可以參考一下2022-02-02Android 自動化測試經(jīng)驗分享 深入UiScrollable
UiScrollable是一個UiCollection(這東西還沒搞懂),我們可以使用它,在可滑動的頁面(水平滑動或上下滑動都可以)上查找我們想要的控件(item)2013-05-05