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); }
android 抽奖盘动画 自定义View
最新推荐文章于 2021-05-25 15:49:27 发布