实现Activity侧滑返回效果

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhiwenyan/article/details/52946726

先看一张效果图

这里写图片描述

通过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触发了侧滑事件,通知其关闭。

猜你喜欢

转载自blog.csdn.net/zhiwenyan/article/details/52946726
今日推荐