仿爱奇艺加载dialog

来源:互联网 发布:mac word 导航窗格 编辑:程序博客网 时间:2024/04/29 19:36

仿爱奇艺在加载视频时的动画,想上张图;



gif的效果有点卡,先说一下实现的方法,

主要的难点在于怎样将三角形画到空间的中间,我通过三角形中心到顶角的距离来确定三角形的大小,


当三角形在中间时角a的大小为60度,线段A的长度为已知的自己设定的,我这里设定的为40像素,则C的长度为

A乘以sin(a)  B的长度为A乘以cos(a);   这里假设空间的长宽各位200的正方形,所以三角形的上顶点的坐标为(100,60),左下顶点为(200 / 2 - A * cos(a)),右顶点的坐标为(200 / 2,A* sin(a)),确定了三角形的三个顶点就可以在通过drawPath画三角形了,代码如下:

path.moveTo(width / 2, height / 2 - length);path.lineTo(formantNumber(width / 2 - Math.sin(Math.PI / 3) * length), width / 2 + length / 2);path.lineTo(formantNumber(width / 2 + Math.sin(Math.PI / 3) * length), width / 2 + length / 2);path.close();

当布局加载完成后开始动画,由于但旋转的时候弧形的扫过的角度为360度,旋转时看不出来圆弧的旋转,

/** * 布局加载完成后开始动画 */@Overrideprotected void onFinishInflate() {    super.onFinishInflate();    startAnimation(rotateAnimation);}

/** * 初始化动画 */private void initRouteAnimation() {    rotateAnimation = new RotateAnimation(0, 1800, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    rotateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());    rotateAnimation.setDuration(1500);    rotateAnimation.setFillAfter(false);    rotateAnimation.setAnimationListener(this);}

当动画执行完后将将扫过的角度设置为0度,重新绘制

/** * 动画介绍后的回调 * * @param animation */@Overridepublic void onAnimationEnd(Animation animation) {    sweepAngle = 0;    isAfterAnimation = true;    invalidate();}

下面是onDraw方法的代码,我在这里判断当扫过的角度为330度的时候,也就是sweepAngle为360的时候,重绘视图,然后开启动画

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    if (isAfterAnimation) {        sweepAngle += 30;        if (sweepAngle >= 360) {            isAfterAnimation = false;            drawPicture(canvas, 360);            startAnimation(rotateAnimation);        } else {            drawPicture(canvas, sweepAngle);            postInvalidateDelayed(30);        }    } else {        drawPicture(canvas, 360);    }}
下面是重写onMeasure方法的代码,在measureWidth方法中判断计算模式,返回空间的宽度,计算模式为wrap_content的时候宽度为200px,计算高度的方法一样,这里不再累赘;


@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    width = measureWidth(widthMeasureSpec);    height = measureHeight(heightMeasureSpec);    setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));}
/** * 计算控件宽度 * * @param widthMeasureSpec * @return */private int measureWidth(int widthMeasureSpec) {    int result = 0;    int mode = MeasureSpec.getMode(widthMeasureSpec);    int size = MeasureSpec.getSize(widthMeasureSpec);    if (mode == MeasureSpec.EXACTLY) {        result = size;    } else {        result = 200;        if (mode == MeasureSpec.AT_MOST) {            result = Math.min(result, size);        }    }    return result;}

完整代码:

package com.example.mengsong.demo01;/** * Created by MengSong on 2016/12/20. */import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.LinearGradient;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Shader;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.animation.AccelerateDecelerateInterpolator;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.view.animation.ScaleAnimation;import android.widget.TextView;/** * Created by MengSong on 2016/12/15. */public class MyView extends View implements Animation.AnimationListener {    //绘制三角形的路径    private Path path;    //绘制三角形的画笔    public Paint mPaintTriangle;    //绘制弧形的画笔    public Paint mPaintArc;    //三角形的中心到顶点的距离    private int length = 40;    //圆弧的半径    private int arcRadius = 80;    //圆弧扫过的角度    private float sweepAngle = 360;    private boolean isAfterAnimation = false;    //旋转动画    private RotateAnimation rotateAnimation;    //圆弧所在的矩形    private RectF rect;    //空间的宽度    private int width;    //控件的高度    private int height;    public MyView(Context context) {        super(context);        init();    }    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    /**     * 布局加载完成后开始动画     */    @Override    protected void onFinishInflate() {        super.onFinishInflate();        startAnimation(rotateAnimation);    }    /**     * 初始化相关属性     */    private void init() {        mPaintTriangle = new Paint();        mPaintTriangle.setDither(true);        mPaintTriangle.setAntiAlias(true);        mPaintTriangle.setStyle(Paint.Style.FILL);        mPaintTriangle.setColor(Color.GREEN);        mPaintArc = new Paint();        mPaintArc.setDither(true);        mPaintArc.setAntiAlias(true);        mPaintArc.setStrokeWidth(3);        mPaintArc.setStyle(Paint.Style.STROKE);        mPaintArc.setColor(Color.GREEN);        path = new Path();        initRouteAnimation();    }    /**     * 初始化三角形的path弧形的所在的矩形     *     * @param w     * @param h     * @param oldw     * @param oldh     */    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        rect = new RectF(width / 2 - arcRadius, height / 2 - arcRadius, width / 2 + arcRadius, height / 2 + arcRadius);        path.moveTo(width / 2, height / 2 - length);        path.lineTo(formantNumber(width / 2 - Math.sin(Math.PI / 3) * length), width / 2 + length / 2);        path.lineTo(formantNumber(width / 2 + Math.sin(Math.PI / 3) * length), width / 2 + length / 2);        path.close();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (isAfterAnimation) {            sweepAngle += 30;            if (sweepAngle >= 360) {                isAfterAnimation = false;                drawPicture(canvas, 360);                startAnimation(rotateAnimation);            } else {                drawPicture(canvas, sweepAngle);                postInvalidateDelayed(30);            }        } else {            drawPicture(canvas, 360);        }    }    private void drawPicture(Canvas canvas, float sweepAngle) {        //画三角形        canvas.drawPath(path, mPaintTriangle);        //画扇形        canvas.drawArc(rect, 270, sweepAngle, false, mPaintArc);    }    /**     * 保留四位小数     *     * @param number     * @return     */    private float formantNumber(double number) {        java.text.DecimalFormat df = new java.text.DecimalFormat("#.####");        String format = df.format(number);        return Float.valueOf(format.trim());    }    /**     * 动画介绍后的回调     *     * @param animation     */    @Override    public void onAnimationEnd(Animation animation) {        sweepAngle = 0;        isAfterAnimation = true;        invalidate();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = measureWidth(widthMeasureSpec);        height = measureHeight(heightMeasureSpec);        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    /**     * 计算控件宽度     *     * @param widthMeasureSpec     * @return     */    private int measureWidth(int widthMeasureSpec) {        int result = 0;        int mode = MeasureSpec.getMode(widthMeasureSpec);        int size = MeasureSpec.getSize(widthMeasureSpec);        if (mode == MeasureSpec.EXACTLY) {            result = size;        } else {            result = 200;            if (mode == MeasureSpec.AT_MOST) {                result = Math.min(result, size);            }        }        return result;    }    /**     * 计算控件高度     *     * @param heightMeasureSpec     * @return     */    private int measureHeight(int heightMeasureSpec) {        int result = 0;        int mode = MeasureSpec.getMode(heightMeasureSpec);        int size = MeasureSpec.getSize(heightMeasureSpec);        if (mode == MeasureSpec.EXACTLY) {            result = size;        } else {            result = 200;            if (mode == MeasureSpec.AT_MOST) {                result = Math.min(result, size);            }        }        return result;    }    /**     * 初始化动画     */    private void initRouteAnimation() {        rotateAnimation = new RotateAnimation(0, 1800, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);        rotateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());        rotateAnimation.setDuration(1500);        rotateAnimation.setFillAfter(false);        rotateAnimation.setAnimationListener(this);    }    @Override    public void onAnimationStart(Animation animation) {    }    @Override    public void onAnimationRepeat(Animation animation) {    }}






1 0