android短视频开发,实现动态点赞出现的点赞动画

android短视频开发,实现动态点赞出现的点赞动画

一、

1 点击一次会撒出五个随机表情和点击音效;

2 连续点击会连续撒出表情并播放音效;

3 长按会一直撒;

4 连续撒时会出现次数和标语(0-20 鼓励,20-40加油,>40太棒了);

 

二、实现过程

2.1 外层布局

因为今日头条里面底部评论框和资讯列表页都会有点赞按钮,那么点赞效果的表情机会满屏幕都存在,所以最外层继承了RelativeLayout。然后宽高都设置match_parent。

在点击按钮的时候触发OnTouch事件:

1
<br>        ivThumbBottom.setOnTouchListener(new View.OnTouchListener() {<br>            @Override<br>            public boolean onTouch(View v, MotionEvent event) {<br>                if (event.getAction() == MotionEvent.ACTION_DOWN) {<br>                    lastDownTime = System.currentTimeMillis();<br>                    //获取到 x y的坐标来确定动画撒表情的起点<br>                    x = (int) event.getRawX();<br>                    y = (int) event.getRawY();<br>                    Log.i("aaa", (System.currentTimeMillis() - lastDownTime) + "");<br>                    handler.postDelayed(mLongPressed, 100);<br>                }<br>                if (event.getAction() == MotionEvent.ACTION_UP) {<br>                    Log.i("aaa", (System.currentTimeMillis() - lastDownTime) + "");<br>                    if (System.currentTimeMillis() - lastDownTime < 100) {//判断为单击事件<br>                        articleThumbRl.setVisibility(View.VISIBLE);<br>                        articleThumbRl.setThumb(true, x, y, articleThumbRl);<br>                        handler.removeCallbacks(mLongPressed);<br>                    } else {//判断为长按事件后松开<br>                        handler.removeCallbacks(mLongPressed);<br>                    }<br>                }<br>                return true;<br>            }<br>        });

 

其中通过如下方式实现,长按循环撒表情。

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

 

2.2 setThumb方法 处理点击事件

1
    public void setThumb(float x, float y, ArticleRl articleThumbRl) {<br>        //这里处理音效播放<br>        if (mMediaPlayer.isPlaying()) {<br>            mMediaPlayer.seekTo(0);//重复点击时,从头开始播放<br>        } else {<br>            mMediaPlayer.start();<br>        }<br>        if (System.currentTimeMillis() - lastClickTime > 800) {//单次点击<br>            addThumbImage(mContext, x, y, this);<br>            lastClickTime = System.currentTimeMillis();<br>            for (int i = getChildCount() - 5; i < getChildCount(); i++) {<br>                if (getChildAt(i) instanceof ThumbEmoji) {<br>                    ((ThumbEmoji) getChildAt(i)).setThumb(true, articleThumbRl);<br>                }<br>            }<br>            currentNumber = 0;<br>            if (thumbNumber != null) {<br>                removeView(thumbNumber);<br>                thumbNumber = null;<br>            }<br>        } else {//连续点击<br>            lastClickTime = System.currentTimeMillis();<br>            Log.i(TAG, "当前动画化正在执行");<br>            addThumbImage(mContext, x, y, this);<br>            for (int i = getChildCount() - 5; i < getChildCount(); i++) {<br>                if (getChildAt(i) instanceof ThumbEmoji) {<br>                    ((ThumbEmoji) getChildAt(i)).setThumb(true, articleThumbRl);<br>                }<br>            }<br>            currentNumber++;<br>            //这里添加数字连击view<br>            LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);<br>            DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();<br>            layoutParams.setMargins(600, (int) (y) - 300, 0, 150);<br>            if (thumbNumber == null) {<br>                thumbNumber = new ThumbNumber(mContext);<br>                addView(thumbNumber, layoutParams);//第二个参数 让数字连击始终保持在最上层<br>            }<br>            thumbNumber.setNumber(currentNumber);<br>        }<br>    }

 

其中,数字连击view中的数字有一个颜色渐变和描边效果,颜色渐变用LinearGradient(扔物线课程里面有),描边用重叠绘制方式。

1
<br>textPaint = new Paint();<br>        textPaint.setTextSize(TEXT_SIZE);<br>        textPaint.setTextAlign(Paint.Align.LEFT);<br>        textPaint.setStrokeWidth(STROKE_WIDTH);<br>        textPaint.setStyle(Paint.Style.FILL);<br>        textPaint.setTypeface(Typeface.DEFAULT_BOLD);<br>        //这里为了做成上面和下面颜色各一半<br>        LinearGradient mLinearGradient = new LinearGradient(0, 0, 0, 90f,<br>                new int[]{0xFFFF9641, 0xFFFF9641, 0xFFFF9641, 0xFFFF9641, 0xFFff0000, 0xFFff0000},<br>                null, Shader.TileMode.CLAMP);<br>        textPaint.setShader(mLinearGradient);<br>        //描边画笔<br>        textPaintStroke = new Paint();<br>        textPaintStroke.setColor(Color.BLACK);<br>        textPaintStroke.setTextSize(TEXT_SIZE);<br>        textPaintStroke.setTextAlign(Paint.Align.LEFT);<br>        textPaintStroke.setStrokeWidth(4);<br>        textPaintStroke.setStyle(Paint.Style.STROKE);<br>        textPaintStroke.setTypeface(Typeface.DEFAULT_BOLD);

 

 

2.3 添加表情的自定义view ThumbEmoji

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

 

 

 

其中这里的addview方法给他设置index为 childcount-1后,就可以让它保持在数字连击view的下方,但是我设置成1会出现bug,的原因我还得再去看看。

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

 

2.4 撒花效果的动画(也就是抛物线动画)的实现

抛物线动画 分为上升和下降两部分,

上升时,x轴匀速左移或右移,y轴减速向上,表情图片宽高从0变到100;

1
下降时,x变为1.2倍x,高度变为最高处的0.8,透明度在最后1/8时间段里从1变为0。<br>       private void showThumbDownAni(ArticleRl articleThumbRl) {<br>        float topX = -(1080 - 200) + (float) ((2160 - 400) * Math.random());<br>        float topY = -300 + (float) (-700 * Math.random());<br>        //上升动画<br>        //抛物线动画 x方向<br>        ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(this, "translationX",<br>                0, topX);<br>        translateAnimationX.setDuration(DURATION);<br>        translateAnimationX.setInterpolator(new LinearInterpolator());<br>        //y方向<br>        ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(this, "translationY",<br>                0, topY);<br>        translateAnimationY.setDuration(DURATION);<br>        translateAnimationY.setInterpolator(new DecelerateInterpolator());<br>        //表情图片的大小变化<br>        ObjectAnimator translateAnimationRightLength = ObjectAnimator.ofInt(this, "rightLength",<br>                0, 100, 100, 100, 100, 100);<br>        translateAnimationRightLength.setDuration(DURATION);<br>        ObjectAnimator translateAnimationBottomLength = ObjectAnimator.ofInt(this, "bottomLength",<br>                0, 100, 100, 100, 100, 100);<br>        translateAnimationBottomLength.setDuration(DURATION);<br>        translateAnimationRightLength.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {<br>            @Override<br>            public void onAnimationUpdate(ValueAnimator animation) {<br>                invalidate();//ondraw会在什么情况下执行?<br>            }<br>        });<br>        //动画集合<br>        AnimatorSet animatorSet = new AnimatorSet();<br>        animatorSet.play(translateAnimationX).with(translateAnimationY).with(translateAnimationRightLength).with(translateAnimationBottomLength);<br>        //下降动画<br>        //抛物线动画,原理:两个位移动画,一个横向匀速移动,一个纵向变速移动,两个动画同时执行,就有了抛物线的效果。<br>        ObjectAnimator translateAnimationXDown = ObjectAnimator.ofFloat(this, "translationX", topX, topX * 1.2f);<br>        translateAnimationXDown.setDuration(DURATION / 5);<br>        translateAnimationXDown.setInterpolator(new LinearInterpolator());<br>        ObjectAnimator translateAnimationYDown = ObjectAnimator.ofFloat(this, "translationY", topY, topY * 0.8f);<br>        translateAnimationYDown.setDuration(DURATION / 5);<br>        translateAnimationYDown.setInterpolator(new AccelerateInterpolator());<br>        //透明度<br>        ObjectAnimator alphaAnimation = ObjectAnimator.ofFloat(this, "alpha", 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0f);<br>        alphaAnimation.setDuration(DURATION / 5);<br>        AnimatorSet animatorSetDown = new AnimatorSet();//设置动画播放顺序<br>        //播放上升动画<br>        animatorSet.start();<br>        animatorSet.addListener(new Animator.AnimatorListener() {<br>        <br>            @Override<br>            public void onAnimationEnd(Animator animation) {<br>                animatorSetDown.play(translateAnimationXDown).with(translateAnimationYDown).with(alphaAnimation);<br>                animatorSetDown.start();<br>            }<br>        });<br>        animatorSetDown.addListener(new Animator.AnimatorListener() {<br>            @Override<br>            public void onAnimationEnd(Animator animation) {<br>                articleThumbRl.removeView(ThumbEmoji.this);<br>                mAnimatorListener.onAnimationEmojiEnd();<br>            }<br>        });<br>    }

 

以上就是android短视频开发,实现动态点赞出现的点赞动画。 更多内容欢迎关注之后的文章

 

posted @   云豹科技-苏凌霄  阅读(352)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示