实现Activity侧滑返回效果

来源:互联网 发布:淘宝怎么追加评价手机 编辑:程序博客网 时间:2024/05/29 05:11

先看一张效果图

这里写图片描述

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

0 0
原创粉丝点击