Ofo开锁界面仿写

代码github,感兴趣的可以一起研究下。为了避免你们没有兴趣看下去,先来一张效果图吧


大体思路:

首先经过观察发现,ofo开锁效果由几个半径不断变化的圆构成,并且圆的颜色的透明度随着半径的不断增大逐渐透明;之余中间的文字的话由于这里不涉及到具体的业务与数据流,所以就通过ValueAnimator不断改变进度,重绘就好了。

关键代码解析:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
    int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
    int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);
    int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
    if (specWidthMode == MeasureSpec.AT_MOST) {
        //宽为wrap_content
        mWidth = DEFAULT_WIDTH;
    } else {
        mWidth = specWidthSize;
    }
    if (specHeightMode == MeasureSpec.AT_MOST) {
        //高为wrap_content
        mHeight = DEFAULT_HEIGHT;
    } else {
        mHeight = specHeightSize;
    }
    setMeasuredDimension(mWidth, mHeight);
    initCircles();

}复制代码

当控件的宽或者高为wrap_content时,给定一个600的默认值,取宽高的较小者作为最大圆的直径。

class Circle {
    long mCreateTime;
    public @ColorInt
    int mColor;

    //最大半径

    public Circle(long circleTime) {
        mCreateTime = circleTime;
    }

    public int getCurrentRadius() {
        float percent = (System.currentTimeMillis() - mCreateTime) % LIFE_DURATION * 1.0f / LIFE_DURATION;
        mColor = ColorUtils.setAlphaComponent(mCircleColor, (int) ((1 - percent) * 255));
        return (int) (percent * mMaxRadius);
    }

    public @ColorInt
    int getColor() {
        return mColor;
    }

}复制代码

Circle抽象了圆的类型,封装了圆当前的半径以及颜色,由于圆的半径和颜色随着时间的变化而变化规则是与一个常数取模运算在除以常数获得一个从0到1再到0重复变化的值,从而觉得当前圆的半径大小以及颜色。

private void initCircles() {
    if (mCircles != null) return;
    if (mMaxRadius <= 0) {
        mMaxRadius = Math.min(mWidth - getPaddingLeft() - getPaddingRight(), mHeight - getPaddingTop() - getPaddingBottom()) / 2;
    }
    int count = LIFE_DURATION / STEP;
    mCircles = new ArrayList<>();
    long currentTime = System.currentTimeMillis() - LIFE_DURATION;
    for (int i = 0; i < count; i++) {
        mCircles.add(new Circle(currentTime + i * STEP));
    }
}复制代码

注意STEP这个常量,表示的是相邻的圆间隔的时间,从而产生颜色以及半径的不同。如果需要圆更加密集把值改小就行。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    for (Circle cirCle : mCircles) {
        drawCircle(canvas, cirCle);
    }
    drawText(canvas);
    if (mIsRun){
        invalidate();
    }
}复制代码

通过在onDraw()里面调用invalidate()方法在进度没有达到100时不断重绘,形成波纹扩散的效果。

代码地址github对你有帮助的话顺手给个星吧,反正不会怀孕!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值