先看一张效果图
通过ViewDragHelper来检测到屏幕侧滑,然后通过内置接口传递给Acitivity触发了侧滑事件,通知其关闭。
1、实现侧滑删除,这里的方法是先要创建一个监听侧滑的自定义布局.
public class SwipeBackLayout extends FrameLayout {
private ViewDragHelper mViewDragHelper;
private View mContentView;
private int mContentWidth;
private boolean isClose;
private int mMoveLeft;
private callBackListener mCallBackListener;
public SwipeBackLayout(Context context) {
this(context, null);
}
public SwipeBackLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwipeBackLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mViewDragHelper = ViewDragHelper.create(this, new ViewDragHelperCallBack());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mViewDragHelper.processTouchEvent(event);
return true;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mContentView = getChildAt(0);
}
protected void setCallBackListener(callBackListener callBackListener) {
this.mCallBackListener = callBackListener;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mContentWidth = this.getWidth();
}
class ViewDragHelperCallBack extends ViewDragHelper.Callback {
//tryCaptureView:捕捉View ---》移动那个View
@Override
public boolean tryCaptureView(View child, int pointerId) {
return child == mContentView;
}
//设置水平拖动的距离
@Override
public int getViewHorizontalDragRange(View child) {
//因为我们移动的是整个界面,所以直接返回整个界面的宽度就可以了
return mContentWidth;
}
//记录值的变化
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
if (changedView == mContentView) {
//记录左边的值的变化,因为我们实现的是往右滑动,所以只记录左边的值就可以了
mMoveLeft = left;
if (isClose || mMoveLeft == mContentWidth) { //mMoveLeft==mContentWidth如果滑动的距离正好等于mContentWidth
//也就是说当前的界面已经滑出屏幕,就回调finish方法,通知activity可以finish了
mCallBackListener.onFinish();
}
}
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//水平移动距离的范围是0~当前界面的宽度,如果left小于0直接返回0,
// 如果大于当前界面的宽度直接返回当前界面宽度
//也就是控制当前界面只能往右移动
return Math.min(mContentWidth, Math.max(left, 0));
}
//手指松开会触发这个方法,做复位操作就在此方法中实现
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
//如果移动的距离大于或等于当前界面的1/5,则触发关闭
if (mMoveLeft >= (mContentWidth / 5)) {
isClose = true;
//设置滑动的View移动位置,即然当前的界面滑出屏幕
mViewDragHelper.settleCapturedViewAt(mContentWidth, releasedChild.getTop());
} else {
//设置滑动的View移动位置,即恢复原来的位置
mViewDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
}
//通知重绘界面
ViewCompat.postInvalidateOnAnimation(SwipeBackLayout.this);
}
}
//view刚初始化的时候就会被调用一次
@Override
public void computeScroll() {
if (mViewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
//回调接口
protected interface callBackListener {
void onFinish();
}
2 侧滑返回的Activity进入和退出的动画
<!--设置Activity进入和退出的动画-->
<style name="SlideRightAnimation" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/slide_in_right</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@anim/slide_out_right</item>
<item name="android:taskOpenEnterAnimation">@anim/slide_in_right</item>
<item name="android:taskOpenExitAnimation">@null</item>
<item name="android:taskCloseEnterAnimation">@null</item>
<item name="android:taskCloseExitAnimation">@anim/slide_out_right</item>
<item name="android:taskToFrontEnterAnimation">@anim/slide_in_right</item>
<item name="android:taskToFrontExitAnimation">@null</item>
<item name="android:taskToBackEnterAnimation">@null</item>
<item name="android:taskToBackExitAnimation">@anim/slide_out_right</item>
</style>
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="250"
android:fromXDelta="100%p"
android:toXDelta="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
</translate>
slide_out_right.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="250"
android:fromXDelta="0"
android:toXDelta="100%p"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
</translate>
<style name="AppTheme.TransparentActivity" parent="Theme.AppCompat.NoActionBar">
<!--设置滑动的Activity背景透明-->
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<!-- android:windowAnimationStyle引入动画 -->
<item name="android:windowAnimationStyle">@style/SlideRightAnimation</item>
</style>
3 设置滑动的Activity的主题为AppTheme.TransparentActivity
<activity
android:name=".SwipeBack.SwipeBackActivity"
android:theme="@style/AppTheme.TransparentActivity">
</activity>
实现这个功能主要是要知道自定义ViewGroup神器ViewDragHelper的用法和Activity进入和退出的动画是怎么设置的;其次的需要设置滑动的Activity背景透明,通过内置接口传递给Acitivity触发了侧滑事件,通知其关闭。
来源:CSDN
作者:小编君
链接:https://blog.csdn.net/zhiwenyan/article/details/52946726