仿美团外卖底部导航栏动画

体验了一下美团外卖的底部导航栏,感觉动画很流畅,分割线被顶起,还有图标的动画,可能用的lottie,觉得分割线被顶起可以自己写动画,所以试着写了一下 。

想自定义view点击实现动画效果,自定义view的区域一定比背景需要被顶起的线要高,所以布局如下:

开始绘制view,被顶起的曲线分三段,前后两端曲线对称的,用path绘制曲线,中间段绘制贝塞尔曲线。

那么我们分别绘制三段曲线,用ValueAnimator实现效果,

    private void initAnim() {
        value = startValue;
        animator = ValueAnimator.ofInt(startValue, halfValue, endValue);
//        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                value = (int) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        animator.setDuration(ANIM_TIME);
        animator.start();
    }

动画执行过程中有个回弹,那么value的变化需要一个中间值,

startValue = 0;
halfValue = -DensityUtils.dp2px(context, 35);
endValue = -DensityUtils.dp2px(context, 25);

在onDraw中绘制曲线代码如下,


        rectF = new RectF((((float)width - (float)contentSize) / 2),
                lineToTop + value,
                (float) width - ((float)width - (float)contentSize) / 2,
                height + value);


        if (value < 0 ) {
            Path path = new Path();
            //绘制第一段圆弧
            path.moveTo(rectF.left - 20, lineToTop);
            float firstCubicHight = ((float) lineToTop - rectF.top) / 4;
            float end = (float) lineToTop - firstCubicHight;
            path.cubicTo(
                    rectF.left - 10,
                    (float) lineToTop - firstCubicHight / 16,
                    rectF.left,
                    (float) lineToTop - firstCubicHight / 12,
                    rectF.left + 10,
                    end
            );

            //绘制第二段圆弧

            path.quadTo(
                    rectF.left + contentSize / 2,
                    rectF.top * 0.9f,
                    rectF.right - 10,
                    end
            );
            //绘制第三段圆弧,和第一段对称

            path.cubicTo(
                    rectF.right,
                    (float) lineToTop - firstCubicHight / 12,
                    rectF.right + 10,
                    (float) lineToTop - firstCubicHight / 16,
                    rectF.right + 20,
                    lineToTop
            );

            Path pathBg = new Path();
            pathBg.addPath(path);

            pathBg.lineTo(rectF.right + 20, height);
            pathBg.lineTo(rectF.left - 20, height);
            pathBg.lineTo(rectF.left - 20, lineToTop);
            canvas.drawPath(pathBg, paintBg);//绘制白色背景

            canvas.drawPath(path, paintBgStroke);//绘制曲线

        }
            

最后在onDraw()中画上图片也用属性动画移动就成功啦。

因为有曲线衔接贝塞尔曲线,不同曲线衔接处的过度在宽屏机器上不是很流畅,有更好的方法欢迎补充!!!

 

下载地址哦!!!!

资源下载地址

 

 

 

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值