`

ViewDragHelper行为测试

阅读更多
只是简单记录一下
以后可能会实现一些效果

import android.content.Context;
import android.graphics.Point;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

/**
 * http://blog.csdn.net/lmj623565791/article/details/46858663
 * http://flavienlaurent.com/blog/2013/08/28/each-navigation-drawer-hides-a-viewdraghelper/
 * http://blog.denevell.org/android-viewdraghelper-example-tutorial.html
 */
public class VDHLayout extends LinearLayout
{
	private View mDragView,mAutoBackView,mEdgeTrackerView;
	
    private ViewDragHelper mDragHelper;

    private Point mAutoBackOriginPos = new Point();
    
    public VDHLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback()
        {
        	//返回ture则表示可以捕获该view;可以根据传入的view参数决定哪些可以拖动
            @Override
            public boolean tryCaptureView(View child, int pointerId)
            {
            	//mEdgeTrackerView禁止直接移动
//                return child == mDragView || child == mAutoBackView;
                return true;
            }

            //控制水平拖动的边界
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx)
            {
            	final int leftBound = getPaddingLeft();
                final int rightBound = getWidth() - child.getWidth() - leftBound;
                final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
                return newLeft;
//                return left;
            }
            //控制垂直拖动的边界
            @Override
            public int clampViewPositionVertical(View child, int top, int dy)
            {
            	final int topBound = getPaddingTop();
                final int bottomBound = getHeight() - child.getHeight() - topBound;
                final int newTop = Math.min(Math.max(top, topBound), bottomBound);
                return newTop;
//                return top;
            }
            
          //手指释放的时候回调
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel)
            {
            	super.onViewReleased(releasedChild, xvel, yvel);
//            	if(yvel>0) {
//                    mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), getMeasuredHeight()-releasedChild.getMeasuredHeight());
//                  } else {
//                    mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);
//                  }
//            	invalidate();
//                //mAutoBackView手指释放时可以自动原路返回
//                if (releasedChild == mAutoBackView)
//                {
//                	//调用settleCapturedViewAt回到初始的位置
//                	mDragHelper.settleCapturedViewAt(mAutoBackOriginPos.x, mAutoBackOriginPos.y);
//                    //需要invalidate()以及结合computeScroll方法一起
//                    invalidate();
//                }
            }

            //在边界拖动时回调
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId)
            {
            	//在onEdgeDragStarted回调方法中,主动通过captureChildView对其进行捕获,该方法可以绕过tryCaptureView,所以我们的tryCaptureView虽然并为返回true,但却不影响
            	//注意如果需要使用边界检测需要添加上mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);。
            	mDragHelper.captureChildView(mEdgeTrackerView, pointerId);
            }
            
            //让clickable=true的子控件也可以拖动
            @Override
            public int getViewHorizontalDragRange(View child)
            {
                 return getMeasuredWidth()-child.getMeasuredWidth();
            }
          //让clickable=true的子控件也可以拖动
            @Override
            public int getViewVerticalDragRange(View child)
            {
                 return getMeasuredHeight()-child.getMeasuredHeight();
            }

            //改变同一个坐标(x,y)去寻找captureView位置的方法。(具体在:findTopChildUnder方法中)
			@Override
			public int getOrderedChildIndex(int index) {
				// TODO Auto-generated method stub
				return super.getOrderedChildIndex(index);
			}
			//true的时候会锁住当前的边界,false则unLock。
			@Override
			public boolean onEdgeLock(int edgeFlags) {
				// TODO Auto-generated method stub
				return super.onEdgeLock(edgeFlags);
			}
			//当触摸到边界时回调。
			@Override
			public void onEdgeTouched(int edgeFlags, int pointerId) {
				// TODO Auto-generated method stub
				super.onEdgeTouched(edgeFlags, pointerId);
			}
			//当captureview被捕获时回调
			@Override
			public void onViewCaptured(View capturedChild, int activePointerId) {
				// TODO Auto-generated method stub
				super.onViewCaptured(capturedChild, activePointerId);
			}
			//当ViewDragHelper状态发生变化时回调(IDLE,DRAGGING,SETTING[自动滚动时])
			@Override
			public void onViewDragStateChanged(int state) {
				// TODO Auto-generated method stub
				super.onViewDragStateChanged(state);
			}
			//当captureview的位置发生改变时回调
			@Override
			public void onViewPositionChanged(View changedView, int left,
					int top, int dx, int dy) {
				// TODO Auto-generated method stub
				super.onViewPositionChanged(changedView, left, top, dx, dy);
			}
            
        });
        
        //如果需要使用边界检测需要添加上
        mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
        
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
//        mDragHelper = ViewDragHelper.create(this, 1.0f, new OurViewDragHelperCallbacks());
    }
    
   @Override
    public boolean onInterceptTouchEvent(MotionEvent event)
    {
//	   final int action = MotionEventCompat.getActionMasked(event);
//	   if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
//	       mDragHelper.cancel();
//	       return false;
//	   }
        return mDragHelper.shouldInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
    	mDragHelper.processTouchEvent(event);
        return true;
    }
    
    @Override
    public void computeScroll()
    {
    	super.computeScroll();
        if(mDragHelper.continueSettling(true))
        {
            invalidate();
//            ViewCompat.postInvalidateOnAnimation(this);
        }
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        super.onLayout(changed, l, t, r, b);

        mAutoBackOriginPos.x = mAutoBackView.getLeft();
        mAutoBackOriginPos.y = mAutoBackView.getTop();
    }

    
    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();
//        mHeaderView = findViewById(R.id.viewHeader);
//        mDescView = findViewById(R.id.viewDesc);
        mDragView = getChildAt(0);
        mAutoBackView = getChildAt(1);
        mEdgeTrackerView = getChildAt(2);
    }
    
}


<com.mb.door.VDHLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:background="#FFff0000"
        android:gravity="center"
        android:text="I can be dragged !" />

    <TextView
        android:layout_width="50dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:background="#FF00FF00"
        android:gravity="center"
        android:text="I can be dragged !" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:background="#FF0000FF"
        android:gravity="center"
        android:text="I can be dragged !" />

</com.mb.door.VDHLayout>


ItemTouchHelper之SwipeDismiss
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0822/3349.html
https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf

ViewDragHelper.CallBack中每个方法的用法
http://m.blog.csdn.net/blog/coder_nice/44678153
分享到:
评论

相关推荐

    使用support.v4包下的ViewDragHelper实现QQ5.0侧滑

    在这个案例中,`ViewDragHelper`是该库的一部分,它允许开发者轻松地实现视图的拖动行为,比如常见的抽屉式导航菜单、滑动关闭对话框等。 在QQ5.0的侧滑效果中,用户可以通过从屏幕边缘向内滑动来触发特定的功能或...

    ViewDragHelper完全解析

    在测试过程中,我们可以模拟不同的拖动场景,检查ViewDragHelper的响应是否符合预期,确保自定义View的行为正确无误。 总之,ViewDragHelper是Android自定义View开发中不可或缺的工具,它简化了处理拖放事件的过程...

    SlideToFinishDemo

    `ViewDragHelper`是Android SDK中的一个工具类,它允许开发者轻松地处理视图拖动事件,创建自定义的触摸行为。 首先,我们需要了解`ViewDragHelper`的基本概念。这是一个帮助我们管理视图拖动的辅助类,它提供了一...

    android实现侧滑功能

    通过`ViewDragHelper`,我们可以轻松地检测滑动手势,并控制子视图的移动范围和行为。 要实现侧滑功能,我们需要遵循以下步骤: 1. **创建自定义`ViewGroup`**:首先,我们需要创建一个继承自`FrameLayout`或`...

    带侧拉菜单tab分页导航并且有信息数目提示的主页框架

    在Android开发中,侧拉菜单常常通过`SlidingDrawer`或`NavigationView`来实现,但在这个项目中,开发者选择使用了`ViewDragHelper`,这是一种自定义手势处理工具,允许更灵活地控制视图的拖动行为。 2. **Tab 分页...

    Android高级应用源码-可拖拽View,仿墨迹天气城市管理.zip

    同时,可能还需要用到`ViewDragHelper`类,它提供了一套方便的API来帮助处理视图的拖放行为。 2. **自定义View**:由于Android系统默认的View可能无法满足所有需求,因此开发者常常需要自定义View。这包括重写`...

    实现左侧滑

    还可以使用`ViewDragHelper`,它是`android.support.v4.widget`包中的一个工具类,特别适合处理子视图的拖动行为。 3. **动画效果**:为了使滑动过程更流畅,通常会添加动画。可以使用`ObjectAnimator`或`...

    自定义android抽屉 修改来自系统,稳定流畅

    如果不想从头开始编写抽屉逻辑,可以考虑使用已有的第三方库,如`Material Design Components`中的`BottomSheetBehavior`或`NavigationView`,它们提供了丰富的定制选项,并且经过了广泛测试,能够提供良好的稳定性...

    国外对左右侧滑菜单的实现SlideMenu

    9. **测试**:在开发过程中,全面的测试是必不可少的,包括不同设备的兼容性测试、手势识别的准确性和稳定性测试,以及动画流畅性测试。 10. **可扩展性**:一个好的SlideMenu实现应该允许开发者轻松添加、修改或...

    LISTVIEW自动上滑,包括侧滑以及colorart

    - 开发者通常会在这样的测试文件中设置断言来验证滑动行为是否正确,如菜单是否能正确滑出和滑入,ListView是否按照预期自动滚动,以及主题颜色是否成功改变。 综上所述,这个项目可能是在构建一个具有动态滚动...

    qqmusic.zip

    10. **测试与调试**:最后,为了确保滑动效果的准确性和稳定性,开发者需要进行广泛的测试,包括单元测试、集成测试和手动测试,找出并修复可能出现的问题。 以上就是“仿qq音乐滑动效果”所涉及的关键知识点,涵盖...

    安卓源码简单的sideMenu.zip

    开发者还可以通过自定义`ViewGroup`或使用`ViewDragHelper`来自定义滑动行为。`ViewDragHelper`是`DrawerLayout`内部使用的工具,可以帮助我们处理子视图的拖动。同时,利用Android的动画框架(如`ObjectAnimator`...

    DragViewAndDelete:拖动GridView并删除

    对于这样的功能,进行全面的测试至关重要,包括单元测试、集成测试以及手动测试,以确保在各种设备和Android版本上的表现都符合预期。 通过以上这些知识点的掌握和实践,开发者可以为Android应用创建一个功能完善...

    多方抽屉效果

    - `ViewDragHelper`是Android提供的一个帮助类,用于处理视图的拖动行为,适用于自定义视图组件的抽屉效果实现。 4. **多方位抽屉**: - 实现多方抽屉效果,需要对每个抽屉的方向进行独立处理。例如,除了常见的...

    Android 模仿QQ 5.0左边侧滑菜单栏

    `GestureDetector`可以识别简单的滑动和点击事件,而`ViewDragHelper`则能帮助我们更精细地控制视图的拖动行为。 4. **动画效果**: - 为了提供流畅的用户体验,菜单的滑出和滑入需要有平滑的动画。可以使用`...

    Android侧边栏效果

    Android系统提供了一些手势检测类,如` GestureDetector`,开发者也可以使用`ViewDragHelper`来自定义滑动行为。 5. **菜单资源**: 侧边栏的菜单项通常由XML资源文件定义,如`res/menu/drawer_menu.xml`。这个...

    安卓Android源码——侧边菜单小例.zip

    - **Android Support Library组件**:使用`androidx.drawerlayout.widget.DrawerLayout`作为主布局,它可以处理滑动行为并管理侧边栏的显示和隐藏。 - **NavigationView**:作为侧边栏内容的容器,可以自定义菜单...

    listivew item 左滑右滑

    10. **测试和调试**:确保在各种设备和屏幕尺寸上测试滑动操作的稳定性和流畅性,调整滑动阈值以适应不同用户的手势习惯。 通过以上步骤,我们可以在ListView的item上实现左滑右滑的效果,为用户提供更加丰富的交互...

    仿QQ滑动出菜单

    `GestureDetector`可以监听简单的滑动事件,而`ViewDragHelper`则更适用于处理视图之间的拖动和滑动行为,更适合创建抽屉式菜单。 3. **自定义ViewGroup**: 为了实现QQ风格的滑动菜单,通常需要自定义一个`...

    android侧边栏滑动效果实现

    - `ViewDragHelper`是Android系统提供的一种帮助类,用于实现拖拽效果,可以用来增强侧边栏的手势识别。 6. **动画效果**: - 可以使用`ObjectAnimator`或`ValueAnimator`为侧边栏的打开和关闭添加平滑的过渡动画...

Global site tag (gtag.js) - Google Analytics