最近发现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
到这里基本就能够实现了,有问题可以留言