上篇android 仿iphoneX上滑退出应用动画(二)已经说明将滑动条添加上去了,该篇给该滑动条添加滑动监听。
在添加的时候可以看到这句:
mSlideView.setOnTouchListener(setOnTouchSlideListener);
用isGoing和isAnimationBackOver来防止过快点击滑动条造成的程序紊乱,用VelocityTracker获取速度值来判断手指滑动停顿(速度为0),
AnimatorSet mScreenshotAnimation;
ValueAnimator oneAnimation;
ValueAnimator twoAnimation ;
float mScaleX,mScaleY;
ImageView mBackgroundIv,mIv;
boolean isOpenRecents = false;
long firstTime=0;
boolean isAnimationBackOver = true;
private boolean isGoing = false;
private VelocityTracker vt=null;
private boolean isUpOrDownSlide;
private int widthPixels,heightPixels;
private View.OnTouchListener setOnTouchSlideListener = new View.OnTouchListener(){
@Override
public boolean onTouch(View view, MotionEvent ev) {
final int action = ev.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
long timeNow = System.currentTimeMillis();
if(timeNow-firstTime>500){
isGoing = true;
}else{
isGoing = false;
}
firstTime = timeNow;
if(isGoing&&isAnimationBackOver) {
WindowManager mWindowManager1 = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display mDisplay = mWindowManager1.getDefaultDisplay();
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
mDisplay.getRealMetrics(mDisplayMetrics);
Matrix mDisplayMatrix = new Matrix();
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
widthPixels = (int) dims[0];
heightPixels = (int) dims[1];
if (!topAppClassName.equals("com.android.systemui.recents.RecentsActivity") && !getTopActivityPackageName().equals("com.mediatek.oobe")/*&&!isInLockScreen()*/ && !topAppPackageName.equals("com.hskj.hometest")) {
if (vt == null) {
//初始化velocityTracker的对象 vt 用来监测motionevent的动作
vt = VelocityTracker.obtain();
} else {
vt.clear();
}
vt.addMovement(ev);
Bitmap mmmBitmap = takeScreenshot();
Bitmap mmBitmap = Bitmap.createBitmap(mmmBitmap, 0, statusBarHeight, widthPixels, heightPixels
- statusBarHeight);
Bitmap mBitmap = getRoundedCornerBitmap(mmBitmap,50f);
mBackgroundIv = new ImageView(mContext);
BitmapDrawable bitmapDrawable = new BitmapDrawable(mContext.getResources(),
"/data/blur_wallpaper.png");
mBackgroundIv.setBackground(bitmapDrawable/*BitmapUtils.scaleBitmap(*//*BitmapUtils.getBlurWallpaper(mContext)*//*mmmbitmap,0.5f)*/);
mBackgroundIv.setAlpha(0f);
mBackgroundIv.setScaleX(1.01f);
mIv = new ImageView(mContext);
mIv.setImageBitmap(BitmapUtils.scaleBitmap(mBitmap,0.5f));
final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
flags,
PixelFormat.TRANSLUCENT);
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
if (getTopActivityPackageName() != "com.hskj.hometest") {
if(mBackgroundIv.getParent()==null) {
mWindowManager.addView(mBackgroundIv, lp);
}
if(mIv.getParent()==null) {
mWindowManager.addView(mIv, lp);
}
}
mScreenshotAnimation = new AnimatorSet();
oneAnimation = createOneAnimation();
twoAnimation = createTwoAnimation();
mScreenshotAnimation.playSequentially(oneAnimation,twoAnimation);
mScreenshotAnimation.setDuration(120);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mBackgroundIv.setAlpha(1f);
}
},100);
}
}
break;
case MotionEvent.ACTION_MOVE:
/*begin add by csc for slide*/
if(isGoing&&isAnimationBackOver&&mIv!=null&&!topAppClassName.equals("com.android.systemui.recents.RecentsActivity")&&!getTopActivityPackageName().equals("com.mediatek.oobe")/*&&!isInLockScreen()*/) {
if (vt != null) {
vt.addMovement(ev);
vt.computeCurrentVelocity(1000);
}
int dy = (int) (ev.getRawY() - mLastY);
if (dy < 0) {//down
isUpOrDownSlide = false;
} else if (dy > 0) {//up
isUpOrDownSlide = true;
}
long instanceY = (int) (ev.getRawY());
if(DEBUG)Log.d("chenshichun"," "+this.getClass().getCanonicalName()+" ::::::1instanceY:::"+instanceY);
DecimalFormat df = new DecimalFormat("0.00");
if (instanceY != 0) {
/*instanceY<0*/
if (-instanceY < 500&&mIv.getScaleX()>=0.5) {
mIv.setScaleX(1 - (float) 0.001 * (heightPixels-instanceY));
mIv.setScaleY(1 - (float) 0.001 * (heightPixels-instanceY));
}
}
mLastY = ev.getRawY();
// if(DEBUG)Log.d("chenshichun"," "+this.getClass().getCanonicalName()+" :::::::vt.getYVelocity::"+ vt.getYVelocity()+":::::::dy::"+dy +" ::::instanceY:: "+instanceY);
if (vt != null) {
if (!isOpenRecents && dy == 0 && vt.getYVelocity() < 0.1 && instanceY < heightPixels-200) { // open recents
Intent showRecentsIntent = new Intent("OPEN_RECENTS_ACTIVITY");
mContext.sendBroadcast(showRecentsIntent);
if(!topAppPackageName.equals("com.hskj.hometest")) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mBackgroundIv.setScaleX(0f);
mBackgroundIv.setScaleY(0f);
mBackgroundIv.setAlpha(1f);
mIv.setAlpha(1f);
mWindowManager.removeView(mBackgroundIv);
mWindowManager.removeView(mIv);
}
}, 200);
}
isOpenRecents = true;
}
}
}
/*end add by csc for slide*/
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL://added by lzp
/*if(!isInLockScreen()){*/
if(isGoing&&isAnimationBackOver) {
if (topAppPackageName.equals("com.hskj.hometest")) {
if (!isOpenRecents) {
Intent showLuncherIntent = new Intent("CLOSE_APP_TO_LUNCHER");
mContext.sendBroadcast(showLuncherIntent);
isOpenRecents = false;
}
} else if (getTopActivityPackageName().equals("com.mediatek.oobe")) {
Intent showLuncherIntent = new Intent("CLOSE_APP_TO_LUNCHER");
mContext.sendBroadcast(showLuncherIntent);
} else {
if (topAppClassName.equals("com.android.systemui.recents.RecentsActivity")) {
if (!isOpenRecents) {
Intent showLuncherIntent = new Intent("CLOSE_APP_TO_LUNCHER");
mContext.sendBroadcast(showLuncherIntent);
isOpenRecents = false;
} else {
isOpenRecents = false;
}
} else {
if (mIv != null) {
if (!isOpenRecents) {
if (!isUpOrDownSlide) {// up
mScaleX = mIv.getScaleX();
mScaleY = mIv.getScaleY();
mScreenshotAnimation.start();
Intent showLuncherIntent = new Intent("CLOSE_APP_TO_LUNCHER");
mContext.sendBroadcast(showLuncherIntent);
} else {// down
startAnimatorBack(mIv);
}
} else {
if (mIv != null && mIv.getParent() != null) {
mWindowManager.removeView(mIv);
}
if (mBackgroundIv != null && mBackgroundIv.getParent() != null) {
mWindowManager.removeView(mBackgroundIv);
}
}
} else {
}
}
}
/*}else{
// do noting
}*/
}
break;
}
return false;
}
};
其中,该方法是将图片处理为圆角
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap,float roundPx){
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
动画:
private ValueAnimator createOneAnimation() {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
// anim.setDuration(200);
anim.setInterpolator(new AccelerateInterpolator());
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator arg0) {
isAnimationBackOver = false;
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
Intent showLuncherIntent = new Intent("CLOSE_APP_TO_LUNCHER");
mContext.sendBroadcast(showLuncherIntent);
}
@Override
public void onAnimationCancel(Animator arg0) {
}
});
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator arg0) {
float t = (Float) arg0.getAnimatedValue();
mIv.setScaleX(mScaleX- (mScaleX-0.5f)*t);
mIv.setScaleY(mScaleY- (mScaleY-0.5f)*t);
}
});
return anim;
}
float mPointX,mPointY;
private ValueAnimator createTwoAnimation() {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 0.5f);
// anim.setDuration(200);
anim.setInterpolator(new AccelerateInterpolator());
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator arg0) {
mPointX = Settings.Global.getFloat(mContext.getContentResolver(), "launcher_x", 0f);
mPointY = Settings.Global.getFloat(mContext.getContentResolver(), "launcher_y", 0f);
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
mBackgroundIv.setAlpha(1f);
mIv.setAlpha(1f);
mBackgroundIv.setScaleX(0f);
mBackgroundIv.setScaleY(0f);
isOpenRecents = false;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mWindowManager.removeView(mBackgroundIv);
mWindowManager.removeView(mIv);
isAnimationBackOver = true;
}
},500);
}
@Override
public void onAnimationCancel(Animator arg0) {
}
});
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator arg0) {
float t = (Float) arg0.getAnimatedValue();
mIv.setScaleX(0.5f - t);
mIv.setScaleY(0.5f - t);
mIv.setPivotX(t*(mPointX-widthPixels/2)/0.5f+widthPixels/2);
mIv.setPivotY(t*(mPointY-heightPixels/2)/0.5f+heightPixels/2);
}
});
return anim;
}
private void startAnimatorBack(ImageView mImageView) {
//透明动画
AnimatorSet set = new AnimatorSet();
ObjectAnimator animatorX = ObjectAnimator.ofFloat(mImageView, "scaleX", mIv.getScaleX(), 1f);
ObjectAnimator animatorY = ObjectAnimator.ofFloat(mImageView, "scaleY", mIv.getScaleX(), 1f);
set.playTogether(animatorX, animatorY);
set.setInterpolator(new AccelerateInterpolator());
set.setDuration(100);
//为动画设置监听
set.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
isAnimationBackOver = false;
}
@Override
public void onAnimationEnd(Animator animator) {
mWindowManager.removeView(mBackgroundIv);
mWindowManager.removeView(mIv);
isAnimationBackOver = true;
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
set.start();
}