仿支付宝笑脸刷新加载动画的实现

看到支付宝的下拉刷新有一个笑脸的动画,因此自己也动手实现一下。效果图如下:
这里写图片描述

一、总体思路

1、静态部分的笑脸。

这一部分的笑脸就是一个半圆弧,加上两颗眼睛,这部分比较简单,用于一开始的展示。

2、动态笑脸的实现。

2.1、先是从底部有一个圆形在运动,运动在左眼位置时把左眼给绘制,同时圆形继续运动,运动到右眼位置时绘制右眼,圆形继续运动到最右边的位置。
2.2、当上面的圆形运动到最右边时候,开始不断绘制脸,从右向左,脸不断增长,这里脸设置为接近半个圆形的大小。
2.3、当脸画完的时候,开始让脸旋转起来,就是一边在增长的同时,另一边是在缩短的。
2.4、最后脸的部分是慢慢缩为一个点的,此时动画结束。
2.5、时间可以看做时最底部的那个圆形运动了两周,因此可以用分数来表示每一部分的运动,如从底部开始到左眼睛的位置,用时比例为(1/4+1/8),最终控制每一部分的动画比例的和加起来为2即可。
大概是这样的时间比例:(1/4+1/8) + (1/4) +(1/8) +(1/2) +(1/4) +(1/4+1/4) ,其中1/4代表1/4个圆弧,也是1/4的时间,其它的类似。

二、代码实现

1、重写onMeasure()方法

处理为wrap_content情况,那么它的specMode是AT_MOST模式,在这种模式下它的宽/高等于spectSize,这种情况下view的spectSize是parentSize,而parentSize是父容器目前可以使用大小,就是父容器当前剩余的空间大小, 就相当于使用match_parent一样 的效果,因此我们可以设置一个默认的值。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpectMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpectSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpectMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpectSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpectMode == MeasureSpec.AT_MOST
                && heightSpectMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mWidth, mHeight);
        } else if (widthSpectMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mWidth, heightSpectSize);
        } else if (heightSpectMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpectSize, mHeight);
        }
    }

2、在构造函数中调用init()方法

进行初始化,之所以看到运动中圆弧能够在右边增长的同时,左边的也在减少是使用PathMeasure类中的getSegment方法来截取任意一段长度的路径。

private void init(Context context, AttributeSet attrs) {
        drawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
                | Paint.FILTER_BITMAP_FLAG);
        lineWidth = dip2px(context, lineWidth);
        radius = dip2px(context, radius);
        path = new Path();
        pathCircle = new Path();
        pathCircle2 = new Path();
        //在path中添加一个顺时针的圆,这时候路径的起点和终点在最后边
        //在画前半部分的脸和运动中的脸,起点在最右边比较方便的计算,但在最后那部分,运动的终点
        //是在圆形的底部,这样把路径圆进行转换到底部,方便计算
        pathCircle.addCircle(0, 0, radius, Direction.CW);
        pathCircle2.addCircle(0, 0, radius, Direction.CW);
        //利用Matrix,让path
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值