package com.laotan.easyreader.ui.activity.base; import android.animation.Animator; import android.animation.ValueAnimator; import android.graphics.Color; import android.graphics.PorterDuff; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.Window; import com.laotan.easyreader.R; import com.laotan.easyreader.http.LifeSubscription; import java.util.LinkedList; import java.util.List; import rx.Subscription; import rx.subscriptions.CompositeSubscription; /** * Created by quantan.liu on 2017/3/21. */ public abstract class BaseActivity extends AppCompatActivity implements LifeSubscription { // 管理运行的所有的activity public final static List<AppCompatActivity> mActivities = new LinkedList<AppCompatActivity>(); public static BaseActivity activity; //一下变量用于从左边滑动到右边关闭的变量 类似ios自带的关闭效果 private int endX; private int startX; private int deltaX; private int endY; private int startY; private int deltaY; private View decorView; private VelocityTracker mVelocityTracker; private boolean isClose = true; @Override protected void onResume() { super.onResume(); activity = this; } @Override protected void onPause() { super.onPause(); activity = null; } protected abstract int getLayoutId(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(getLayoutId()); mVelocityTracker = mVelocityTracker.obtain(); decorView = getWindow().getDecorView(); synchronized (mActivities) { mActivities.add(this); } } /** * 子类可以直接用 * * @param title */ protected void setToolBar(Toolbar toolbar, String title) { toolbar.setTitle(title); setSupportActionBar(toolbar); toolbar.setTitleTextColor(Color.WHITE); getSupportActionBar().setDisplayHomeAsUpEnabled(true);//显示toolbar的返回按钮 getSupportActionBar().setDisplayShowHomeEnabled(true); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { onBackPressed(); } }); } private CompositeSubscription mCompositeSubscription; //用于添加rx的监听的在onDestroy中记得关闭不然会内存泄漏。 @Override public void bindSubscription(Subscription subscription) { if (this.mCompositeSubscription == null) { this.mCompositeSubscription = new CompositeSubscription(); } this.mCompositeSubscription.add(subscription); } @Override protected void onDestroy() { super.onDestroy(); synchronized (mActivities) { mActivities.remove(this); } if (this.mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { this.mCompositeSubscription.unsubscribe(); } } public void killAll() { // 复制了一份mActivities 集合Å List<AppCompatActivity> copy; synchronized (mActivities) { copy = new LinkedList<>(mActivities); } for (AppCompatActivity activity : copy) { activity.finish(); } // 杀死当前的进程 android.os.Process.killProcess(android.os.Process.myPid()); } //下面的用于侧滑关闭Activity public void touchFinish() { super.finish(); overridePendingTransition(R.anim.alpha_enter, R.anim.alpha_exit); } /** * 关闭activity时执行这个动画 * * @param deltaX */ public void closeAnimator(int deltaX) { if (isClose) { ValueAnimator animator = ValueAnimator.ofInt(deltaX, decorView.getWidth()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (Integer) animation.getAnimatedValue(); // decorView.layout(value, 0, value + decorView.getWidth(), decorView.getHeight()); decorView.scrollTo(-value, 0); } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animator arg0) { } @Override public void onAnimationEnd(Animator arg0) { if (isClose) { touchFinish(); } } @Override public void onAnimationCancel(Animator arg0) { } }); animator.setDuration(300); animator.start(); } else { ValueAnimator animator = ValueAnimator.ofInt(deltaX, 0); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (Integer) animation.getAnimatedValue(); // decorView.layout(value, 0, value + decorView.getWidth(), decorView.getHeight()); decorView.scrollTo(-value, 0); } }); animator.setDuration(300); animator.start(); } } // 需要测滑关闭时在打开这个注释 @Override public boolean dispatchTouchEvent(MotionEvent ev) { mVelocityTracker.addMovement(ev); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: startX = (int) ev.getRawX(); startY = (int) ev.getRawY(); if (startX < getWindow().getDecorView().getWidth() / 32) { return true; } else { return super.dispatchTouchEvent(ev); } case MotionEvent.ACTION_MOVE: endX = (int) ev.getRawX(); endY = (int) ev.getRawY(); deltaX = endX - startX; deltaY = endY - startY; if (deltaX > deltaY && startX < getWindow().getDecorView().getWidth() / 32) { decorView.scrollTo(-deltaX, 0); decorView.getBackground().setColorFilter((Integer) evaluateColor((float) deltaX / (float) decorView.getWidth(), Color.BLACK, Color.TRANSPARENT), PorterDuff.Mode.SRC_OVER); return true; } else { return super.dispatchTouchEvent(ev); } case MotionEvent.ACTION_UP: mVelocityTracker.computeCurrentVelocity(1000); float xVelocity = mVelocityTracker.getXVelocity(); if (-25 < xVelocity && xVelocity <= 50 && deltaX > decorView.getWidth() / 3 && startX < getWindow().getDecorView().getWidth() / 32 || xVelocity > 50 && startX < getWindow().getDecorView().getWidth() / 32) { isClose = true; closeAnimator(deltaX); return true; } else { if (deltaX > 0 && startX < getWindow().getDecorView().getWidth() / 32) { isClose = false; closeAnimator(deltaX); return true; } else { if (startX < getWindow().getDecorView().getWidth() / 32) { decorView.scrollTo(0, 0); } return super.dispatchTouchEvent(ev); } } case MotionEvent.ACTION_CANCEL: mVelocityTracker.clear(); mVelocityTracker.recycle(); return super.dispatchTouchEvent(ev); } return super.dispatchTouchEvent(ev); } /** * 颜色变化过度 * * @param fraction * @param startValue * @param endValue * @return */ public Object evaluateColor(float fraction, Object startValue, Object endValue) { int startInt = (Integer) startValue; int startA = (startInt >> 24) & 0xff; int startR = (startInt >> 16) & 0xff; int startG = (startInt >> 8) & 0xff; int startB = startInt & 0xff; int endInt = (Integer) endValue; int endA = (endInt >> 24) & 0xff; int endR = (endInt >> 16) & 0xff; int endG = (endInt >> 8) & 0xff; int endB = endInt & 0xff; return (startA + (int) (fraction * (endA - startA))) << 24 | (startR + (int) (fraction * (endR - startR))) << 16 | (startG + (int) (fraction * (endG - startG))) << 8 | (startB + (int) (fraction * (endB - startB))); } }