1. Effect demonstration

I haven’t updated my article for a long time, so I decided to work overtime to update an article. I have just entered a new environment and am slowly adapting to it. In addition, the pace of Shenzhen is relatively fast, and my leisure time is getting less and less. Therefore, I will share a simple effect encountered in my work this time. This effect took me nearly half a day, so let’s take a look:

It’s cool to get a new task and feel the designer effects come out. The first thought is not to go to the Internet to find, find should be white, calm down to analyze.

Two. Effect analysis and realization

First of all, we will certainly want to ask the designer to give a GIF image, but these progress can be controlled by the background, so the simple GIF image is certainly not possible. So we can only customize the View to implement. The background of the red envelope and progress bar gives two pictures, and the explosion effect also gives two pictures of elements. It is actually quite simple to analyze:

1. First of all, we can achieve the progress bar effect; 2. Second, the explosion effect will be realized after the progress bar animation is executed; 3. Finally, when the progress bar is full, the zoom in explosion effect is realized.

Step is this step, the key is how do you write the code? If we’re already familiar with custom views, it’s easy to write, just a matter of time. And the most difficult question we can think of is how do adaptations work? One of our phones might work just fine, but what about the others? After writing, if there is a lag and how to optimize? There are a lot of questions, but it’s not that hard to actually write.

1. First of all, we can achieve the progress bar effect

@override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {Override protected void onMeasure(int widthMeasureSpec, int heightMeasure) { Why more than 0.1 is due to the explosion effect int size = (int) (Math. Max (mRedPackageBitmap. GetWidth (), mRedPackageBitmap. GetHeight ()) * 1.1 f); super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(size, size); } @override protected void onDraw(Canvas Canvas) {int viewHeight = getHeight(); int viewWidth = getWidth(); DrawBitmap (mRedPackageBitmap, 0, 0, null); drawBitmap(mRedPackageBitmap, 0, 0, null); / / draw the progress bar background, must match the red envelope position, can only be calculated in proportion, but also fit all models int progressBgWidth = mProgressBgBitmap. GetWidth (); Int left = (int) (progressBgWidth * 0.09f); int top = viewHeight - mProgressBgBitmap.getHeight() - left; canvas.drawBitmap(mProgressBgBitmap, left, top, null); // Draw progressif(mTotalProgress == 0 || mCurrentProgress == 0){
            return; } / / these only slowly to debug, not any related to px dp units that can only be in proportion to debug int progressHeight = (int) (mProgressBgBitmap. GetHeight () * 0.25 f);floatProgressWidth = viewWidth * 0.64 f; int currentProgressWidth = (int) (progressWidth*mCurrentProgress/mTotalProgress); int round = progressHeight/2; Shader Shader = new LinearGradient(0, 0, progressWidth, 0, new int[]{mProgressStarColor,mProgressEndColor}, newfloat[]} {0, 1.0 f, Shader. TileMode. CLAMP); mProgressPaint.setShader(shader); Top = (int) (top * 1.19 f); Left = (int) (left * 2.5 f); RectF rectF = new RectF(left,top,left+currentProgressWidth,top+progressHeight); canvas.drawRoundRect(rectF,round,round,mProgressPaint); } public void startAnimator(int from, int to) {public void startAnimator(int from, int to) { to).setDuration(PROGRESS_EXECUTE_TIME); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener{@override public void onAnimationUpdate(ValueAnimator animation) {Float current = (Float) animation.getAnimatedValue();setCurrentProgress(current); }}); animator.start(); }Copy the code

2. Secondly, the explosion effect will be realized after the progress bar animation is executed

// Draw the explosion effectif(mBombProgress > 0 && mBombProgress < 1) {// Each Anglefloat preAngle = (float) (2 * Math.PI / mBombIcon.length);
    for(int i = 0; i < 8; I ++) {// double Angle = I * preAngle; // Set transparency to mBombpaint.setalpha ((int) (320-mBombProgress * 255));float cx = (float) (bombCenterX + mProgressBombRadius * mBombProgress * Math.cos(angle));
      float cy = (float) (bombCenterY + mProgressBombRadius * mBombProgress * Math.sin(angle)); canvas.drawBitmap(mBombIcon[i % 2], cx, cy, mBombPaint); }} // Draw the explosion animation private voidexecuteDisperseBombAnimator() {

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1f).setDuration(BOMB_EXECUTE_TIME);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mBombProgress = (float) animation.getAnimatedValue(); invalidate(); }}); animator.setInterpolator(new DecelerateInterpolator()); animator.start(); animator.addListener(newAnimatorListenerAdapter() {@override public void onAnimationEnd(Animator animation)if (mCurrentProgress == mTotalProgress) {
                
                }
            }
        });
    }
Copy the code

3. Finally, when the progress bar is full, the zoom in explosion effect is realized.

/** * perform minification */ private voidexecuteShrinkAnimator() {
        if(mShrinkAnimators == null) { mShrinkAnimators = new AnimatorSet(); ObjectAnimator scaleX = objectAnimator.offloat (this,"scaleX", 1f, SHRINK_SCALE);
            ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1f, SHRINK_SCALE); mShrinkAnimators.setDuration(SHRINK_EXECUTE_TIME); mShrinkAnimators.setInterpolator(new DecelerateInterpolator()); mShrinkAnimators.play(scaleX).with(scaleY); Mshrinkanimators.start (); mShrinkAnimators.addListener(newAnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { // mHandler.sendEmptyMessageDelayed(0x0011, 200); executeMagnifyAnimator(); }}); } mShrinkAnimators.start(); mHandler.sendEmptyMessageDelayed(0x0022, SHRINK_EXECUTE_TIME - 100); } /** * perform the zoom effect */ private voidexecuteMagnifyAnimator() {

        if(mMagnifyAnimators == null) { mMagnifyAnimators = new AnimatorSet(); ObjectAnimator scaleX = objectAnimator.offloat (this,"scaleX", SHRINK_SCALE, 1f);
            ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", SHRINK_SCALE, 1f); mMagnifyAnimators.setDuration(MAGNIFY_EXECUTE_TIME); mMagnifyAnimators.setInterpolator(new DecelerateInterpolator()); mMagnifyAnimators.play(scaleX).with(scaleY); / / two animation began mMagnifyAnimators. At the same time addListener (newAnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mHandler.sendEmptyMessageDelayed(0x0011, ANIMATION_STOP_TIME); }}); } mMagnifyAnimators.start(); }Copy the code

Video link: https://pan.baidu.com/s/1cAYBfuhR1WquroYjakftfg video password: h7w6