生活随笔
收集整理的這篇文章主要介紹了
SurfaceView实现抽奖转盘
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在慕課上看了鴻洋大神的課程,在此記錄下來,小伙伴們可以直接去網站下載素材,傳送門
幸運轉盤類
package com
.example
.surfaceviewdemo
;import android
.content
.Context
;
import android
.graphics
.Bitmap
;
import android
.graphics
.BitmapFactory
;
import android
.graphics
.Canvas
;
import android
.graphics
.Color
;
import android
.graphics
.Paint
;
import android
.graphics
.Path
;
import android
.graphics
.Rect
;
import android
.graphics
.RectF
;
import android
.util
.AttributeSet
;
import android
.util
.Log
;
import android
.util
.TypedValue
;
import android
.view
.SurfaceHolder
;
import android
.view
.SurfaceView
;
public class LuckyPan extends SurfaceView implements SurfaceHolder.Callback, Runnable
{private SurfaceHolder mHolder
;private Canvas mCanvas
;private Thread t
;private boolean isRunning
;private String
[] mStrs
= new String[]{"單反相機", "IPAD", "恭喜發財", "IPHONE", "服裝一套", "恭喜發財"};private int[] mImgs
= new int[]{R
.drawable
.danfan
, R
.drawable
.ipad
, R
.drawable
.f040
, R
.drawable
.iphone
, R
.drawable
.meizi
, R
.drawable
.f015
};private int[] mColors
= new int[]{0xFFFFC300, 0XFFF17E10, 0xFFFFC300, 0XFFF17E10, 0xFFFFC300, 0XFFF17E10};private Bitmap
[] mImgsBitmap
;private Bitmap mBgBitmap
= BitmapFactory
.decodeResource(getResources(), R
.drawable
.bg2
);private int mItemCount
= 6;private RectF mRange
= new RectF();private int mRadius
;private Paint mArcPaint
;private Paint mTextPaint
;private float mTextSize
= TypedValue
.applyDimension(TypedValue
.COMPLEX_UNIT_SP
, 20, getResources().getDisplayMetrics());private double mSpeed
= 0;private volatile float mStartAngle
= 0;private int mCenter
;private int mPadding
;private boolean isShouldEnd
;public LuckyPan(Context context
) {this(context
, null
);}public LuckyPan(Context context
, AttributeSet attrs
) {super(context
, attrs
);mHolder
= getHolder();mHolder
.addCallback(this);setFocusable(true);setFocusableInTouchMode(true);setKeepScreenOn(true);}@Overrideprotected void onMeasure(int widthMeasureSpec
, int heightMeasureSpec
) {super.onMeasure(widthMeasureSpec
, heightMeasureSpec
);int width
= Math
.min(getMeasuredWidth(), getMeasuredHeight());mPadding
= getPaddingLeft();mRadius
= width
- mPadding
* 2;mCenter
= width
/ 2;setMeasuredDimension(width
, width
);}@Overridepublic void surfaceCreated(SurfaceHolder holder
) {mArcPaint
= new Paint();mArcPaint
.setAntiAlias(true);mArcPaint
.setDither(true);mTextPaint
= new Paint();mTextPaint
.setColor(Color
.WHITE
);mTextPaint
.setTextSize(mTextSize
);mRange
= new RectF(mPadding
, mPadding
, mPadding
+ mRadius
, mPadding
+ mRadius
);mImgsBitmap
= new Bitmap[mItemCount
];for (int i
= 0; i
< mItemCount
; i
++) {mImgsBitmap
[i
] = BitmapFactory
.decodeResource(getResources(), mImgs
[i
]);}isRunning
= true;t
= new Thread(this);t
.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder
, int format
, int width
, int height
) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder
) {isRunning
= false;}@Overridepublic void run() {while (isRunning
) {long start
= System
.currentTimeMillis();draw();long end
= System
.currentTimeMillis();if (end
- start
< 50) {try {Thread
.sleep(50 - (end
- start
));} catch (InterruptedException e
) {e
.printStackTrace();}}}}private void draw() {try {mCanvas
= mHolder
.lockCanvas();if (mCanvas
!= null
) {drawBg();float tempAngle
= mStartAngle
;float sweepAngle
= 360 / mItemCount
;for (int i
= 0; i
< mItemCount
; i
++) {mArcPaint
.setColor(mColors
[i
]);mCanvas
.drawArc(mRange
, tempAngle
, sweepAngle
, true, mArcPaint
);drawText(tempAngle
, sweepAngle
, mStrs
[i
]);drawIcon(tempAngle
, mImgsBitmap
[i
]);tempAngle
+= sweepAngle
;}mStartAngle
+= mSpeed
;if (isShouldEnd
) {mSpeed
-= 1;}if (mSpeed
<= 0) {mSpeed
= 0;}}} catch (Exception e
) {} finally {if (mCanvas
!= null
)mHolder
.unlockCanvasAndPost(mCanvas
);}}public void luckyStart(int index
) {float angle
= 360 / mItemCount
;float from
= 270 - (index
+ 1) * angle
;float end
= from
+ angle
;float targetFrom
= 4 * 360 + from
;float targetEnd
= 4 * 360 + end
;float v1
= (float) ((-1 + Math
.sqrt(1 + 8 * targetFrom
)) / 2);float v2
= (float) ((-1 + Math
.sqrt(1 + 8 * targetEnd
)) / 2);mSpeed
= v1
+ Math
.random() * (v2
- v1
);isShouldEnd
= false;}public void luckyEnd() {mStartAngle
= 0;isShouldEnd
= true;}public boolean isStart() {return mSpeed
!= 0;}public boolean isShouldEnd() {return isShouldEnd
;}private void drawIcon(float tempAngle
, Bitmap mImg
) {int imgWidth
= mRadius
/ 8;float angle
= (float) ((tempAngle
+ 360 / mItemCount
/ 2) * Math
.PI
/ 180);int x
= (int) (mCenter
+ mRadius
/ 2 / 2 * Math
.cos(angle
));int y
= (int) (mCenter
+ mRadius
/ 2 / 2 * Math
.sin(angle
));Rect rect
= new Rect(x
- imgWidth
/ 2, y
- imgWidth
/ 2, x
+ imgWidth
/ 2, y
+ imgWidth
/ 2);mCanvas
.drawBitmap(mImg
, null
, rect
, null
);}private void drawText(float tempAngle
, float sweepAngle
, String mStr
) {Path path
= new Path();path
.addArc(mRange
, tempAngle
, sweepAngle
);float mTextWidth
= mTextPaint
.measureText(mStr
);int hOffset
= (int) ((mRadius
* Math
.PI
/ mItemCount
) / 2 - mTextWidth
/ 2);int vOffset
= mRadius
/ 2 / 6;mCanvas
.drawTextOnPath(mStr
, path
, hOffset
, vOffset
, mTextPaint
);}private void drawBg() {Log
.d("TAG", "drawBg: ");mCanvas
.drawColor(Color
.WHITE
);mCanvas
.drawBitmap(mBgBitmap
, null
, new Rect(mPadding
/ 2, mPadding
/ 2, getMeasuredWidth() - mPadding
/ 2, getMeasuredHeight() - mPadding
/ 2), null
);}
}
測試類
package com
.example
.surfaceviewdemo
;import androidx
.appcompat
.app
.AppCompatActivity
;import android
.os
.Bundle
;
import android
.view
.View
;
import android
.widget
.ImageView
;public class MainActivity extends AppCompatActivity {private LuckyPan mLuckyPan
;private ImageView mStartBtn
;@Overrideprotected void onCreate(Bundle savedInstanceState
) {super.onCreate(savedInstanceState
);setContentView(R
.layout
.activity_main
);mLuckyPan
= findViewById(R
.id
.luckyPan
);mStartBtn
= findViewById(R
.id
.start_btn
);mStartBtn
.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v
) {if (!mLuckyPan
.isStart()) {mLuckyPan
.luckyStart(2);mStartBtn
.setImageResource(R
.drawable
.stop
);} else {if (!mLuckyPan
.isShouldEnd()) {mLuckyPan
.luckyEnd();mStartBtn
.setImageResource(R
.drawable
.start
);}}}});}
}
測試布局
<?xml version
="1.0" encoding
="utf-8"?>
<RelativeLayout xmlns
:android
="http://schemas.android.com/apk/res/android"xmlns
:app
="http://schemas.android.com/apk/res-auto"xmlns
:tools
="http://schemas.android.com/tools"android
:layout_width
="match_parent"android
:layout_height
="match_parent"android
:background
="@android:color/white"tools
:context
=".MainActivity"><com
.example
.surfaceviewdemo
.LuckyPanandroid
:id
="@+id/luckyPan"android
:layout_width
="match_parent"android
:layout_height
="match_parent"android
:layout_centerInParent
="true"android
:padding
="30dp"></com
.example
.surfaceviewdemo
.LuckyPan
><ImageViewandroid
:id
="@+id/start_btn"android
:layout_width
="wrap_content"android
:layout_height
="wrap_content"android
:layout_centerInParent
="true"android
:src
="@drawable/start" /></RelativeLayout
>
總結
以上是生活随笔為你收集整理的SurfaceView实现抽奖转盘的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。