Android中仿ios侧滑退出activity

最近发现ios中大部分页面都可以通过侧滑来退出上个页面,于是自己研究了一下

首先创建了一个监听侧滑的类

import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;

public class SwipeBackController {
    private static final String TAG = SwipeBackController.class.getSimpleName();
    public static final int ANIMATION_DURATION = 300;//默认动画时间
    public static final int DEFAULT_TOUCH_THRESHOLD = 60;//默认开始滑动的位置距离左边缘的距离

//    private WeakReference mActivityWR;

    private int mScreenWidth;
    private int mTouchSlop;

    private boolean isMoving = false;
    private float mInitX;
    private float mInitY;

    private ViewGroup decorView;//窗口根布局
    private ViewGroup contentView;//content布局
    private ViewGroup userView;//用户添加的布局

    private ArgbEvaluator evaluator;
    private ValueAnimator mAnimator;
    private VelocityTracker mVelTracker;

    public SwipeBackController(final Activity activity) {
        mScreenWidth = activity.getResources().getDisplayMetrics().widthPixels;
        mTouchSlop = ViewConfiguration.get(activity).getScaledTouchSlop();
        evaluator = new ArgbEvaluator();

        decorView = (ViewGroup) activity.getWindow().getDecorView();
        decorView.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00ffffff")));
        contentView = (ViewGroup) activity.findViewById(android.R.id.content);
        userView = (ViewGroup) contentView.getChildAt(0);

        mAnimator = new ValueAnimator();
        mAnimator.setDuration(ANIMATION_DURATION);
        mAnimator.setInterpolator(new DecelerateInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int x = (Integer) valueAnimator.getAnimatedValue();
                if (x >= mScreenWidth) {
                    activity.finish();
                }

                handleView(x);
                handleBackgroundColor(x);
            }
        });
    }

    public void handleView(int x) {
        userView.setTranslationX(x);
    }
    /**
     * 控制背景颜色和透明度
     * @param x
     */
    private void handleBackgroundColor(float x) {
        int colorValue = (int) evaluator.evaluate(x / mScreenWidth,
                Color.parseColor("#dd000000"), Color.parseColor("#00000000"));
        contentView.setBackgroundColor(colorValue);
        Log.d(TAG, "x is " + x);
    }

    public boolean processEvent(MotionEvent event) {
        getVelocityTracker(event);

        if (mAnimator.isRunning()) {
            return true;
        }

        int pointId = -1;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mInitX = event.getRawX();
                mInitY = event.getRawY();
                pointId = event.getPointerId(0);
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isMoving) {
                    float dx = Math.abs(event.getRawX() - mInitX);
                    float dy = Math.abs(event.getRawY() - mInitY);
                    if (dx > mTouchSlop && dx > dy && mInitX < DEFAULT_TOUCH_THRESHOLD) {
                        isMoving = true;
                    }
                }
                if (isMoving) {
                    handleView((int) event.getRawX());
                    handleBackgroundColor(event.getRawX());
                }

                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                int distance = (int) (event.getRawX() - mInitX);

                mVelTracker.computeCurrentVelocity(1000);
                //获取x方向上的速度
                float velocityX = mVelTracker.getXVelocity(pointId);

                Log.d(TAG, "mVelocityX is " + velocityX);
                if (isMoving && Math.abs(userView.getTranslationX()) >= 0) {
                    if (velocityX > 1000f || distance >= mScreenWidth / 4) {
                        mAnimator.setIntValues((int) event.getRawX(), mScreenWidth);
                    } else {
                        mAnimator.setIntValues((int) event.getRawX(), 0);
                    }
                    mAnimator.start();
                    isMoving = false;
                }

                mInitX = 0;
                mInitY = 0;

                recycleVelocityTracker();
                break;
        }
        return true;
    }

    /**
     * 获取速度追踪器
     *
     * @return
     */
    private VelocityTracker getVelocityTracker(MotionEvent event) {
        if (mVelTracker == null) {
            mVelTracker = VelocityTracker.obtain();
        }
        mVelTracker.addMovement(event);
        return mVelTracker;
    }

    /**
     * 回收速度追踪器
     */
    private void recycleVelocityTracker() {
        if (mVelTracker != null) {
            mVelTracker.clear();
            mVelTracker.recycle();
            mVelTracker = null;
        }
    }
}

在要退出的activity的代码如下

public class Main2Activity extends AppCompatActivity {
    private SwipeBackController swipeBackController;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main2);

        swipeBackController = new SwipeBackController(this);
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (swipeBackController.processEvent(ev)) {
            return true;
        } else {
            return super.onTouchEvent(ev);
        }
    }
}

其中要主页的地方是requestWindowFeature(Window.FEATURE_NO_TITLE)这行代码一定要写到setContentView之前,否则会报一个错误,不相信的可以试一下哦

布局是这样的


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    tools:context="${relativePackage}.${activityClass}"
    >
    <ImageView
        android:id="@+id/imv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffff9f"/>
    <TextView
        android:layout_marginTop="20dp"
        android:id="@+id/txt"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="30dp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:textColor="@android:color/black"
        android:text="这是页面滑动销毁的例子"/>

RelativeLayout>

这个时候会发现退出的时候是黑的,不太美观,我们就要在清单文件中将要退出的activity主题设置成透明的

<activity
            android:name=".Main2Activity"
            android:theme="@android:style/Theme.Translucent" />

如果你运行发现报了没有这个主题那就是说明你不是用的import android.app.Activity这个包的activity

那如果你要用import android.support.v7.app.AppCompatActivity这个,就要自定义透明主题

首先要在res的values中的color文件中加入透明颜色

<color name="transparent">#00000000

然后在values的style中加入自定义主题

最后就是在清单文件调用自定义主题

<activity
            android:name=".Main2Activity"
            android:theme="@style/TranslucentFullScreenTheme" />

demo地址:http://download.csdn.net/download/dang321580/10222180

到这里基本就能够实现了,有问题可以留言

你可能感兴趣的:(Android中仿ios侧滑退出activity)