android 抽奖盘动画 自定义View

public class LotterPlate extends View {

    private Context context;

    private Paint dPaint = new Paint();
    private Paint sPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


    private int[] images = new int[]{R.mipmap.huawei,R.mipmap.image_one,R.mipmap.iphone,R.mipmap.macbook,R.mipmap.meizu,R.mipmap.xiaomi};

    private String[] strs = {"0","1","2","3","4","5"};
    private List<Bitmap> bitmaps = new ArrayList<>();
    private ScrollerCompat scroller;

    private  ValueAnimator unfromanimtor;
    private int InitAngle = -150;
    private int radius = 0;
    private int number=images.length;
    private  int flag=360/number;
    private  int DesRotate;
    public interface AnimationEndListener{
        void endAnimation(int position);
    }

    private AnimationEndListener valueAnimatorListenter;
    //    动画结束回调
    public void setAnimationEndListener(AnimationEndListener valueAnimatorListenter){
        this.valueAnimatorListenter = valueAnimatorListenter;
    }
    public LotterPlate(Context context) {
        this(context,null);
    }

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

    public LotterPlate(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;

        scroller = ScrollerCompat.create(context);

        dPaint.setColor(Color.rgb(255,133,132));
        dPaint.setStrokeWidth(74);
        dPaint.setAntiAlias(true);
        dPaint.setStyle(Paint.Style.STROKE);

        sPaint.setColor(Color.BLACK);
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(Util.dip2px(context,16));
        for(int i=0;i<number;i++){
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), images[i]);
            bitmaps.add(bitmap);
        }

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //wrap_content value
        int mHeight = dip2px(context, 450);
        int mWidth = dip2px(context, 450);

        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(mWidth, mHeight);
        }else if(widthSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(mWidth, heightSpecSize);
        }else if(heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(widthSpecSize, mHeight);
        }
    }

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

            final int paddingLeft = getPaddingLeft();
            final int paddingRight = getPaddingRight();
            final int paddingTop = getPaddingTop();
            final int paddingBottom = getPaddingBottom();

            int width = getWidth() - paddingLeft - paddingRight;
            int height = getHeight() - paddingTop - paddingBottom;

            int MinValue = Math.min(width,height);

            radius = MinValue/2;

            RectF rectF = new RectF(getPaddingLeft()+250,getPaddingTop()+250,width-250,height-250);  //调整圆的半径

            for(int i= 0;i<number;i++){
                drawIcon(width/2, height/2, radius+100, InitAngle, i, canvas);
                canvas.drawArc(rectF,InitAngle-flag/2,1f,false,dPaint);
                drawText(InitAngle+flag/2,strs[i], radius, textPaint, canvas,rectF);
                InitAngle += flag;
        }

    }

    private void drawText(float startAngle, String string,int mRadius,Paint mTextPaint,Canvas mCanvas,RectF mRange)
    {
        Path path = new Path();
        path.addArc(mRange, startAngle, flag);
        float textWidth = mTextPaint.measureText(string);

        float hOffset = (float) (mRadius * Math.PI / 7 / 2 - textWidth / 2);
        float vOffset = mRadius / 2/4 ;
        mCanvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);

    }

    private void drawIcon(int xx,int yy,int mRadius,float startAngle, int i,Canvas mCanvas)
    {

        int imgWidth = mRadius / 4;

        float angle = (float) Math.toRadians(flag+startAngle);

        float x = (float) (xx + mRadius/3*2   * Math.cos(angle));
        float y = (float) (yy + mRadius/3*2   * Math.sin(angle));

        // 确定绘制图片的位置
        RectF rect = new RectF(x - imgWidth *3/ 4, y - imgWidth*3 / 4, x + imgWidth
                *3/ 4, y + imgWidth*3/4);

        Bitmap bitmap = bitmaps.get(i);

        mCanvas.drawBitmap(bitmap, null, rect, null);

    }


    public void setImages(List<Bitmap> bitmaps){
        this.bitmaps = bitmaps;
        this.invalidate();
    }

    public void setStr(String... strs){
        this.strs = strs;
        this.invalidate();
    }

    //旋转一圈所需要的时间
    private static final long ONE_WHEEL_TIME = 1000;


    /**
     * 开始转动
     * @param pos 如果 pos = -1 则随机,如果指定某个值,则转到某个指定区域
     */
    public void startRotate(int pos){

        int lap = (int) (Math.random()*12);

        int angle = 0;
        if(pos < 0){
            angle = (int) (Math.random() * 360);
        }else{
            int initPos  = queryPosition();
            if(pos > initPos){
                angle = (pos - initPos)*60;
                lap -= 1;
                angle = 360 - angle;
            }else if(pos < initPos){
                angle = (initPos - pos)*60;
            }else{
                //nothing to do.
            }
        }

        int increaseDegree = lap * 360 + angle;
        long time = (lap + angle / 360) * ONE_WHEEL_TIME;
         DesRotate = increaseDegree + InitAngle;
        int offRotate = DesRotate % 360 % flag;
        DesRotate -= offRotate;
        DesRotate += 30;
//        ferrisWheel(time,InitAngle,DesRotate);
        turntable(time,InitAngle,DesRotate);
//        unfromanimtor.cancel();

    }

    public void unifromAnim(){  //匀速旋转
        clearAnimation();
         unfromanimtor = ValueAnimator.ofInt(0,360);
        unfromanimtor.setInterpolator(new LinearInterpolator());
        unfromanimtor.setDuration(2000);
        unfromanimtor.setRepeatCount(-1);
        unfromanimtor.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int updateValue = (int) animation.getAnimatedValue();
                InitAngle = (updateValue % 360 + 360) % 360;
                ViewCompat.postInvalidateOnAnimation(LotterPlate.this);

            }
        });
        unfromanimtor.start();


    }

    private void ferrisWheel( long time,int starAngle,int endAngle){ // TODO: 2017/7/6 图片会随位置改变而调整角度
        ValueAnimator  valueAnimator = ValueAnimator.ofInt(starAngle,endAngle);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.setDuration(time);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int updateValue = (int) animation.getAnimatedValue();
                InitAngle = (updateValue % 360 + 360) % 360;
                ViewCompat.postInvalidateOnAnimation(LotterPlate.this);
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if(valueAnimatorListenter != null)
                    valueAnimatorListenter.endAnimation(queryPosition());
            }
        });
        valueAnimator.start();
        clearAnimation();
    }
    private void turntable(long time,int startAngle,int endAngle){ // TODO: 2017/7/6 图片自身不会变动
        RotateAnimation rotate  = new RotateAnimation(startAngle, endAngle, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotate.setInterpolator(new LinearInterpolator());
        rotate.setDuration(time);//设置动画持续时间
        rotate.setRepeatCount(0);//设置重复次数
        rotate.setFillAfter(true);//动画执行完后是否停留在执行完的状态
        startAnimation(rotate);
        rotate.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {}
            @Override
            public void onAnimationEnd(Animation animation) {

                if(valueAnimatorListenter != null) {
                    InitAngle=DesRotate;
                    int index=queryPosition();
                    valueAnimatorListenter.endAnimation(index);

                    for(int i=0;i<index;i++){
                        bitmaps.add(bitmaps.size(),bitmaps.get(i));
                        bitmaps.remove(i);
                    }
                }
            }
            @Override
            public void onAnimationRepeat(Animation animation) {}
        });
    }


    //查寻初始位置  可根据需求调整
    private int queryPosition(){
        InitAngle = (InitAngle % 360 + 360) % 360;
        int pos = InitAngle / flag;
        return calcumAngle(pos);
    }

    private int calcumAngle(int pos){
        if(pos >= 0 && pos <= 3){
            pos = 3 - pos;
        }else{
            pos = (6-pos) + 3;
        }
        return pos;
    }
 


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        clearAnimation();
    }


    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

猜你喜欢

转载自blog.csdn.net/dk_clay/article/details/74529166