ViewDragHelper实现右划关闭Activity

这段时间学习了ViewDragHelper的使用,觉得挺牛逼的,使用起来也特别的方便。它可以方便的让我们处理触摸事件,是否分发,是否处理,一句话,使用它你可以忽略touch过程中的一些细节了!!

先看看ViewDragHelper的创建吧!

ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {}通过一个create的静态方法就可以获取到ViewDragHelper的一个实体。

这里需要传入一个Callback;

接下来重点说说这个Callback;它里面有很多的方法。。

ViewDragHelper实现右划关闭Activity_第1张图片

搂一眼之后还是先来看看ViewDragHelper的几个重要的方法。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return mViewDragHelper.shouldInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    mViewDragHelper.processTouchEvent(event);
    return true;
    //这里一定要记得返回true;
}

通过这两个方法的设定,那么我们的触摸事件就移交给ViewDragHelper了,让它帮我处理是否要中断传播和处理触摸相关的事件。

获取到填充的布局:

 @Override
protected void onFinishInflate() {
    super.onFinishInflate();
    //该布局中应该只有一个子布局,所有的其他布局填充到这个子布局中。
    mContentView = getChildAt(0);
}

onLayout()的方法中得到view的宽度!!

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    mContentWidth = mContentView.getWidth();
}

接下来看看Callback的相关代码:

@Override
public boolean tryCaptureView(View child, int pointerId) {
    return child == mContentView;//只有mContentView可以移动
}

@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
    mMoveLeft = left;
    if (mCallBack != null) {
        mCallBack.onPositionChanged(left, top, dx, dy);
    }
    if (isClose && (left == mContentWidth)) {
        if (mCallBack != null) {
            mCallBack.onFinish();
        }
        activity.finish();

    }
}

@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
    if (mMoveLeft >= (mContentWidth / 2)) {
        //滑动超过屏幕的一半,那么就可以判断为true了!
        isClose = true;
        mViewDragHelper.settleCapturedViewAt(mContentWidth, releasedChild.getTop());
    } else {
        mViewDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
    }
    invalidate();
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {

  return left;
}
@Override
public int getViewHorizontalDragRange(View child) {
    //一定要重写这个方法,返回>0的值,不然当子View可以消耗触摸事件时就会无法移动。
    return mContentWidth;
}

tryCaptureView()的方法就是返回是否可以操作。

onViewPositionChanged()就是位置发生变化时的相关回调。

onViewReleased()这个就是当我们抬起手,释放的操作时。我们的相关判断其实就是在这个方法中完成的。如果移动的距离大于等于屏幕宽度的一半,那么在释放的时候我们就finish当前的Activity

clampViewPositionHorizontal()返回建议的left就好!

getViewHorizontalDragRange() 如果我们滑动的控件可以消费触摸事件,那么为了可以成功的移动它,我们必须得重写这个方法,返回值>0就好!

最后复写一下

 @Override
public void computeScroll() {
    super.computeScroll();
    if (mViewDragHelper.continueSettling(true)) {
        invalidate();
    }
}

到这里就完了哇??哈哈,还没有呢!因为你会发现这样你弄的的确可以滑动了,但是看不到下面的Activity啊!!这是什么鬼??最后还得给Activity设置为透明的背景。


配置这两个属性,基本上就大功告成了!!

nono..是不是Activity划出去之后还有屏幕一闪一闪的情况?那可能是因为Activity默认的动画效果。
所以在上面finish()是应该再设置一下(这两句话的位置不能反了!):

 this.finish();
 this.overridePendingTransition(0, 0);//取消Activity的动画。//取消Activity的动画。

最后的最后,如果你想让Activity的开启动画变成是从左到右的,那么也设置一下就好:
对应的就是:

activity_in



activity_out




  • 更新:

之前的代码使用的话,会出现Activity左右都能滑动。

 @Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
    //这样的话,页面就只能向右滑动了!
  return Math.min(mContentWidth, Math.max(left, 0));
}

如果需要实现边界触摸才有效果的话:需要做如下修改:

1.实现边界滑动的回调,在里面处理对应的view!

@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
    super.onEdgeDragStarted(edgeFlags, pointerId);
    //在里面处理我们需要实现边界滑动有效的view
    mViewDragHelper.captureChildView(mContentView, pointerId);
}

2.设置边界滑动可用:

 mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);

这里当然是左边有效啦!

3.最后需要将之前的tryCaptureView()的方法中的mContentView的相关逻辑注释掉!

Demo下载
as直接导入module!
GitHub

你可能感兴趣的:(趣味杂谈)