自定义View--操作动画

这里写图片描述

计算

这里写图片描述

这里写图片描述

/*
 * Created by Hanks
 * Copyright (c) 2015 Nashangban. All rights reserved
 *
 */
package app.hanks.com.customanimateview.OpAnimateView;

import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import app.hanks.com.customanimateview.R;

/**
 * Created by Hanks on 2015/5/27.
 */
public class OpAnimationView extends View {

    private Paint paint;
    private Paint paintShadow;

    private int width;
    private int height;
    private int c;

    private boolean isAnimating  = false;    //is isAnimating?
    private boolean isRgihtShape = false;    //is in right_shap?

    private float progress;        //animation‘s progress
    private int DURATION = 300;      // animation DURATION
    private int r;        //randius
    private int shadowWidth;        //shadow randius
    private int defaultShapeWidth;
    private int shapeWidth;

    public OpAnimationView(Context context) {
        this(context, null);
    }

    public OpAnimationView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public OpAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public OpAnimationView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * init paint
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    private void init(Context context, AttributeSet attrs, int defStyleAttr) {

        defaultShapeWidth = dp2px(4);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        paintShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
        setLayerType(LAYER_TYPE_SOFTWARE, paintShadow);

        shadowWidth = dp2px(4);
        paintShadow.setShadowLayer(shadowWidth, 0.0f, dp2px(2), Color.parseColor("#66000000"));


        // load the styled attributes and set their properties
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.OpAnimationView, defStyleAttr, 0);

        setBackgroundColor(attributes.getColor(R.styleable.OpAnimationView_backgroundColor, Color.parseColor("#FF4081")));
        setShapeColor(attributes.getColor(R.styleable.OpAnimationView_shapeColor, Color.parseColor("#ffffff")));
        shapeWidth = attributes.getDimensionPixelOffset(R.styleable.OpAnimationView_shapeWidth, defaultShapeWidth);
        setShapeWidth(shapeWidth);

        // We no longer need our attributes TypedArray, give it back to cache
        attributes.recycle();

    }


    private List<PointF> points = new ArrayList<>();

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        r = Math.min(w, h) / 2 - shadowWidth;
        float g2 = (float) Math.sqrt(2);
        c = (int) (r / g2);
        float dis = r - c + dp2px(4);

        points.clear();
        points.add(new PointF(c + dis, c / 3f + dis));
        points.add(new PointF(c + dis, c * 5f / 3f + dis));
        points.add(new PointF(c / 3f + dis, c + dis));
        points.add(new PointF(c * 5f / 3f + dis, c + dis));
        points.add(new PointF(c * (1 + 3 * g2) / 3f + dis, c * (3 - g2) / 3f + dis));
        points.add(new PointF(c * (1 + g2) / 3f + shapeWidth / g2 / 2 + dis, c * (3 + g2) / 3f + shapeWidth / g2 / 2 + dis));
        points.add(new PointF(c * (1 + g2) / 3f - shapeWidth / g2 / 2 + dis, c * (3 + g2) / 3f + shapeWidth / g2 / 2 + dis));
    }

    //set background circle color
    public void setBackgroundColor(int color) {
        paintShadow.setColor(color);
    }

    //set center shape color
    public void setShapeColor(int color) {
        paint.setColor(color);
    }

    public void setShapeWidth(int width) {
        paint.setStrokeWidth(width);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.drawCircle(width / 2, height / 2, r, paintShadow);

        if (isRgihtShape) { // right --> add
            float x0 = (points.get(0).x - points.get(4).x) * progress + points.get(4).x;
            float y0 = (points.get(0).y - points.get(4).y) * progress + points.get(4).y;
            float x1 = (points.get(1).x - points.get(6).x) * progress + points.get(6).x;
            float y1 = (points.get(1).y - points.get(6).y) * progress + points.get(6).y;

            float x2 = points.get(2).x;
            float y2 = points.get(2).y;
            float x3 = (points.get(3).x - points.get(5).x) * progress + points.get(5).x;
            float y3 = (points.get(3).y - points.get(5).y) * progress + points.get(5).y;
            canvas.drawLine(x0, y0, x1, y1, paint);
            canvas.drawLine(x2, y2, x3, y3, paint);

        } else { //add --> right

            float x0 = (points.get(4).x - points.get(0).x) * progress + points.get(0).x;
            float y0 = (points.get(4).y - points.get(0).y) * progress + points.get(0).y;
            float x1 = (points.get(6).x - points.get(1).x) * progress + points.get(1).x;
            float y1 = (points.get(6).y - points.get(1).y) * progress + points.get(1).y;

            float x2 = points.get(2).x;
            float y2 = points.get(2).y;
            float x3 = (points.get(5).x - points.get(3).x) * progress + points.get(3).x;
            float y3 = (points.get(5).y - points.get(3).y) * progress + points.get(3).y;
            canvas.drawLine(x0, y0, x1, y1, paint);
            canvas.drawLine(x2, y2, x3, y3, paint);
        }
    }

    public boolean isRightShape() {
        return isRgihtShape;
    }

    /**
     * add_shape to right_shape
     */
    public void add2right() {
        if (isAnimating) {
            return;
        }
        progress = 0f;
        isAnimating = true;
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(DURATION);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                progress = (float) animation.getAnimatedValue();
                if (progress >= 1) {
                    isRgihtShape = true;
                    isAnimating = false;
                } else {
                    invalidate();
                }
            }
        });
        valueAnimator.start();
    }


    /**
     * right_shape  to add_shape
     */
    public void right2add() {
        if (isAnimating) {
            return;
        }
        progress = 0f;
        isAnimating = true;
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(DURATION);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                progress = (float) animation.getAnimatedValue();
                if (progress >= 1) {
                    isRgihtShape = false;
                    isAnimating = false;
                } else {
                    invalidate();
                }
            }
        });
        valueAnimator.start();
    }

    /**
     * dpת px.
     *
     * @param value the value
     * @return the int
     */
    public int dp2px(float value) {
        final float scale = getResources().getDisplayMetrics().densityDpi;
        return (int) (value * (scale / 160) + 0.5f);
    }
}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="OpAnimationView">
        <attr name="backgroundColor" format="color"></attr>
        <attr name="shapeColor" format="color"></attr>
        <attr name="shapeWidth" format="dimension"></attr>
    </declare-styleable>
</resources>

源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值