android 仿iphoneX上滑退出应用动画(三)
16lz
2021-01-24
上篇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(); }
更多相关文章
- 2013.12.04 (7)——— android SlidingMenu之CustomAnimation
- Android(安卓)简易音乐动态相册(多种动画)
- android异步加载网络图片
- 开源直播系统源码Android中activity跳转动画效果
- Android(安卓)多线程通信 Handler
- Android学习笔记(6)——Android——LoginDemo
- android GPS HAL 回调函数实现
- android TV开发:弹出菜单实现
- Android(安卓)动画实现