android短視訊開發,實現動態點贊出現的點贊動畫

zhibo系統開發發表於2021-12-20

android短視訊開發,實現動態點贊出現的點贊動畫

一、

1 點選一次會撒出五個隨機表情和點選音效;

2 連續點選會連續撒出表情並播放音效;

3 長按會一直撒;

4 連續撒時會出現次數和標語(0-20 鼓勵,20-40加油,>40太棒了);


二、實現過程

2.1 外層佈局

因為今日頭條裡面底部評論框和資訊列表頁都會有點贊按鈕,那麼點贊效果的表情機會滿螢幕都存在,所以最外層繼承了RelativeLayout。然後寬高都設定match_parent。

在點選按鈕的時候觸發OnTouch事件:

        ivThumbBottom.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    lastDownTime = System.currentTimeMillis();
                    //獲取到 x y的座標來確定動畫撒表情的起點
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();
                    Log.i("aaa", (System.currentTimeMillis() - lastDownTime) + "");
                    handler.postDelayed(mLongPressed, 100);
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    Log.i("aaa", (System.currentTimeMillis() - lastDownTime) + "");
                    if (System.currentTimeMillis() - lastDownTime < 100) {//判斷為單擊事件
                        articleThumbRl.setVisibility(View.VISIBLE);
                        articleThumbRl.setThumb(true, x, y, articleThumbRl);
                        handler.removeCallbacks(mLongPressed);
                    } else {//判斷為長按事件後鬆開
                        handler.removeCallbacks(mLongPressed);
                    }
                }
                return true;
            }
        });



其中通過如下方式實現,長按迴圈撒表情。

    final Runnable mLongPressed = new Runnable() {
        @Override
        public void run() {
            articleThumbRl.setVisibility(View.VISIBLE);
            articleThumbRl.setThumb(x, y, articleThumbRl);
            handler.postDelayed(mLongPressed, 100);
        }
    };


2.2 setThumb方法 處理點選事件

    public void setThumb(float x, float y, ArticleRl articleThumbRl) {
        //這裡處理音效播放
        if (mMediaPlayer.isPlaying()) {
            mMediaPlayer.seekTo(0);//重複點選時,從頭開始播放
        } else {
            mMediaPlayer.start();
        }
        if (System.currentTimeMillis() - lastClickTime > 800) {//單次點選
            addThumbImage(mContext, x, y, this);
            lastClickTime = System.currentTimeMillis();
            for (int i = getChildCount() - 5; i < getChildCount(); i++) {
                if (getChildAt(i) instanceof ThumbEmoji) {
                    ((ThumbEmoji) getChildAt(i)).setThumb(true, articleThumbRl);
                }
            }
            currentNumber = 0;
            if (thumbNumber != null) {
                removeView(thumbNumber);
                thumbNumber = null;
            }
        } else {//連續點選
            lastClickTime = System.currentTimeMillis();
            Log.i(TAG, "當前動畫化正在執行");
            addThumbImage(mContext, x, y, this);
            for (int i = getChildCount() - 5; i < getChildCount(); i++) {
                if (getChildAt(i) instanceof ThumbEmoji) {
                    ((ThumbEmoji) getChildAt(i)).setThumb(true, articleThumbRl);
                }
            }
            currentNumber++;
            //這裡新增數字連擊view
            LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
            layoutParams.setMargins(600, (int) (y) - 300, 0, 150);
            if (thumbNumber == null) {
                thumbNumber = new ThumbNumber(mContext);
                addView(thumbNumber, layoutParams);//第二個引數 讓數字連擊始終保持在最上層
            }
            thumbNumber.setNumber(currentNumber);
        }
    }


其中,數字連擊view中的數字有一個顏色漸變和描邊效果,顏色漸變用LinearGradient(扔物線課程裡面有),描邊用重疊繪製方式。

textPaint = new Paint();
        textPaint.setTextSize(TEXT_SIZE);
        textPaint.setTextAlign(Paint.Align.LEFT);
        textPaint.setStrokeWidth(STROKE_WIDTH);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTypeface(Typeface.DEFAULT_BOLD);
        //這裡為了做成上面和下面顏色各一半
        LinearGradient mLinearGradient = new LinearGradient(0, 0, 0, 90f,
                new int[]{0xFFFF9641, 0xFFFF9641, 0xFFFF9641, 0xFFFF9641, 0xFFff0000, 0xFFff0000},
                null, Shader.TileMode.CLAMP);
        textPaint.setShader(mLinearGradient);
        //描邊畫筆
        textPaintStroke = new Paint();
        textPaintStroke.setColor(Color.BLACK);
        textPaintStroke.setTextSize(TEXT_SIZE);
        textPaintStroke.setTextAlign(Paint.Align.LEFT);
        textPaintStroke.setStrokeWidth(4);
        textPaintStroke.setStyle(Paint.Style.STROKE);
        textPaintStroke.setTypeface(Typeface.DEFAULT_BOLD);



2.3 新增表情的自定義view ThumbEmoji

     private void addThumbImage(Context context, float x, float y, ThumbEmoji.AnimatorListener animatorListener) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            list.add(i);
        }
        Collections.shuffle(list);//打亂順序
        for (int i = 0; i < 5; i++) {
            LayoutParams layoutParams = new LayoutParams(100, 100);
            layoutParams.setMargins((int) x, (int) y - 50, 0, 0);
            ThumbEmoji articleThumb = new ThumbEmoji(context);
            articleThumb.setEmojiType(list.get(i));
            articleThumb.setmAnimatorListener(animatorListener);
            if (getChildCount() > 1)
                this.addView(articleThumb, getChildCount() - 1, layoutParams);
            else {
                this.addView(articleThumb, layoutParams);
            }
        }
    }




其中這裡的addview方法給他設定index為 childcount-1後,就可以讓它保持在數字連擊view的下方,但是我設定成1會出現bug,的原因我還得再去看看。

 if (getChildCount() > 1)
                this.addView(articleThumb, getChildCount() - 1, layoutParams);
            else {
                this.addView(articleThumb, layoutParams);
            }


2.4 撒花效果的動畫(也就是拋物線動畫)的實現

拋物線動畫 分為上升和下降兩部分,

上升時,x軸勻速左移或右移,y軸減速向上,表情圖片寬高從0變到100;

下降時,x變為1.2倍x,高度變為最高處的0.8,透明度在最後1/8時間段裡從1變為0。
       private void showThumbDownAni(ArticleRl articleThumbRl) {
        float topX = -(1080 - 200) + (float) ((2160 - 400) * Math.random());
        float topY = -300 + (float) (-700 * Math.random());
        //上升動畫
        //拋物線動畫 x方向
        ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(this, "translationX",
                0, topX);
        translateAnimationX.setDuration(DURATION);
        translateAnimationX.setInterpolator(new LinearInterpolator());
        //y方向
        ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(this, "translationY",
                0, topY);
        translateAnimationY.setDuration(DURATION);
        translateAnimationY.setInterpolator(new DecelerateInterpolator());
        //表情圖片的大小變化
        ObjectAnimator translateAnimationRightLength = ObjectAnimator.ofInt(this, "rightLength",
                0, 100, 100, 100, 100, 100);
        translateAnimationRightLength.setDuration(DURATION);
        ObjectAnimator translateAnimationBottomLength = ObjectAnimator.ofInt(this, "bottomLength",
                0, 100, 100, 100, 100, 100);
        translateAnimationBottomLength.setDuration(DURATION);
        translateAnimationRightLength.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                invalidate();//ondraw會在什麼情況下執行?
            }
        });
        //動畫集合
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(translateAnimationX).with(translateAnimationY).with(translateAnimationRightLength).with(translateAnimationBottomLength);
        //下降動畫
        //拋物線動畫,原理:兩個位移動畫,一個橫向勻速移動,一個縱向變速移動,兩個動畫同時執行,就有了拋物線的效果。
        ObjectAnimator translateAnimationXDown = ObjectAnimator.ofFloat(this, "translationX", topX, topX * 1.2f);
        translateAnimationXDown.setDuration(DURATION / 5);
        translateAnimationXDown.setInterpolator(new LinearInterpolator());
        ObjectAnimator translateAnimationYDown = ObjectAnimator.ofFloat(this, "translationY", topY, topY * 0.8f);
        translateAnimationYDown.setDuration(DURATION / 5);
        translateAnimationYDown.setInterpolator(new AccelerateInterpolator());
        //透明度
        ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(this, "alpha", 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0f);
        alphaAnimation.setDuration(DURATION / 5);
        AnimatorSet animatorSetDown = new AnimatorSet();//設定動畫播放順序
        //播放上升動畫
        animatorSet.start();
        animatorSet.addListener(new Animator.AnimatorListener() {
        
            @Override
            public void onAnimationEnd(Animator animation) {
                animatorSetDown.play(translateAnimationXDown).with(translateAnimationYDown).with(alphaAnimation);
                animatorSetDown.start();
            }
        });
        animatorSetDown.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationEnd(Animator animation) {
                articleThumbRl.removeView(ThumbEmoji.this);
                mAnimatorListener.onAnimationEmojiEnd();
            }
        });
    }


以上就是android短視訊開發,實現動態點贊出現的點贊動畫。 更多內容歡迎關注之後的文章


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2848566/,如需轉載,請註明出處,否則將追究法律責任。

相關文章