生活随笔
收集整理的這篇文章主要介紹了
Android--大转盘
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
前言
無論是線上推廣,還是線下營銷,轉盤游戲都是非常吸引人的一項活動,就像電視劇《贅婿》中的“拼刀刀”,達到的是萬人空巷的影響力。其實,這是一種賭徒心理。每個人都希望不勞而獲,這是賭徒心理的成長的肥沃土壤,不幸的是,千百萬年的成長中,人已經形成了避難趨易的本性。轉盤是一種傻瓜式的操作,只需要手指點一下,不過幾秒鐘,就可以收到反饋。而想要立即得到結果,害怕未知依然是每個人的本質。所以,轉盤游戲有其滋生的土壤。
思考
怎么樣實現一個轉盤那?首先:轉盤是一個圓,然后把圓等分成幾份,每一份都是一個扇形區域,在扇形區域中畫出我們先展示的內容,接著,中間可能有裝飾(圖片),最后,按照層級一層層畫。
想必大家都對自定義View的過程了熟于心,這里就不過多介紹了。下面我們進入代碼。
代碼
自定義轉盤
這里沒有給出全部的代碼,而是抽取了一些關鍵步驟,文章的最后有給出全部代碼。
class LuckySpinView : View {constructor(context: Context?) : super(context) {initPaint()}// 初始化畫筆。自定義View前先想好需要哪些畫筆,對實現View有神奇效果private fun initPaint() {mArcPaint = Paint()mArcPaint.isAntiAlias = truemArcPaint.isDither = truemTextPaint = TextPaint()mTextPaint.style = Paint.Style.FILLmTextPaint.isAntiAlias = truemTextPaint.isDither = truemTextPaint.color = mTextColormTextPaint.textSize = mTextSizemTextPaint.typeface = ResourcesCompat.getFont(context, R.font.impact)mTextStrokePaint = TextPaint(mTextPaint)mTextStrokePaint.style = Paint.Style.STROKEmTextStrokePaint.strokeWidth = TEXT_STROKE_WIDTHmBackgroundPaint = Paint()mBackgroundPaint.isAntiAlias = truemBackgroundPaint.isDither = true}// 測量階段。自定義View必要的階段,用來規范我們View的展示大小override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {super.onMeasure(widthMeasureSpec, heightMeasureSpec)val width = measuredWidth.coerceAtMost(measuredHeight)mPadding = paddingLeftif (mOutRadius == 0) mOutRadius = width / 2if (mInnerRadius == 0) mInnerRadius = width / 2setMeasuredDimension(mOutRadius * 2, mOutRadius * 2)}// 繪畫階段。自定義View必要的階段,畫布承載我們想要的效果,畫筆將我們的想法變成現實/*** @param canvas*/@SuppressLint("DrawAllocation")override fun onDraw(canvas: Canvas) {super.onDraw(canvas)drawArc(canvas) // 畫扇形區域drawCenterImg(canvas) //畫中間的區域drawOutBoundImg(canvas) // 畫外圍的裝飾}@SuppressLint("UseCompatLoadingForDrawables")private fun drawCenterImg(canvas: Canvas) {if (mCenterImageId == 0) returnif (mCenterBitmap == null) {val drawable = resources.getDrawable(mCenterImageId, null)val bitmap = Utils.drawableToBitmap(drawable)mCenterBitmap = Bitmap.createScaledBitmap(bitmap,drawable!!.intrinsicWidth,drawable.intrinsicHeight,false)}val bitmap = mCenterBitmap!!canvas.drawBitmap(bitmap, mCenterPoint.x - bitmap.width / 2.toFloat(),mCenterPoint.y - bitmap.height / 2.toFloat(), null)}@SuppressLint("UseCompatLoadingForDrawables")private fun drawOutBoundImg(canvas: Canvas) {val drawable = resources.getDrawable(mBackgroundImgId, null)drawable.bounds = Rect(mOutRange.left.toInt() ,mOutRange.top.toInt() ,mOutRange.right.toInt() ,mOutRange.bottom.toInt())drawable.draw(canvas)}private fun drawArc(canvas: Canvas) {var tmpAngle = mStartAngleval sweepAngle = 360f / mRewardList.sizefor (i in mRewardList.indices) {fillArc(canvas, tmpAngle, sweepAngle, i)drawArcBorder(canvas, tmpAngle, sweepAngle)drawItemContentWithoutIcon(i, canvas, tmpAngle, sweepAngle)tmpAngle += sweepAngle}}private fun rotateTo(index: Int) {HandlerUtils.runOnUiThread {val rand = Random()rotateTo(index, rand.nextInt() and 1, true)}}// 執行旋轉fun rotateTo(index: Int, rotation: Int, startShow: Boolean) {if (isRunning) {return}val rotationAssess = if (rotation <= 0) 1 else -1var roundOfNumber = mRoundOfNumberval accDuration = 1500Lvar decDuration = 1500Lvar interpolator: TimeInterpolator// 從上一次轉盤最終的位置處旋轉if (getRotation() != 0.0f) {setRotation(getRotation() % 360f)interpolator = AccelerateInterpolator()animate().setInterpolator(interpolator).setDuration(accDuration).setListener(object : Animator.AnimatorListener {override fun onAnimationStart(animation: Animator) {isRunning = true}override fun onAnimationEnd(animation: Animator) {isRunning = falsesetRotation(0f) // 加速到角度為0的水平軸, 接著再減速到目標角度rotateTo(index, rotation, false)}override fun onAnimationCancel(animation: Animator) {}override fun onAnimationRepeat(animation: Animator) {}}).rotation(360f * roundOfNumber * rotationAssess).start()return}interpolator = DecelerateInterpolator()// 進入轉盤后的第一次玩轉盤, 先加速再減速if (startShow) {roundOfNumber = roundOfNumber shl 1decDuration = accDuration shl 1interpolator = AccelerateDecelerateInterpolator()}val targetAngle =360f * roundOfNumber * rotationAssess + 270f - getAngleOfIndexTarget(index) - 360f / mRewardList.size / 2animate().setInterpolator(interpolator).setDuration(decDuration + 500L).setListener(object : Animator.AnimatorListener {override fun onAnimationStart(animation: Animator) {isRunning = true}override fun onAnimationEnd(animation: Animator) {isRunning = falsesetRotation(getRotation() % 360f)if (mRotateListener != null) {mRotateListener!!.rotateDone(index)}}override fun onAnimationCancel(animation: Animator) {}override fun onAnimationRepeat(animation: Animator) {}}).rotation(targetAngle).start()}fun setTargetIndex(index: Int) {targetIndex = index}// 開始旋轉fun startLuckyWheelWithTargetIndex(index: Int) {this.rotateTo(index)}fun startLuckyWheelWithRandomTarget() {val r = Random()this.rotateTo(r.nextInt(this.rewardListSize - 1))}// 取消旋轉fun cancelRotate() {animate().cancel()}
}
這里有全部的代碼,歡迎查看,LuckySpin
總結
在實現轉盤游戲的過程中,總會碰到一些攔路虎。如果避其鋒芒,不敢與之對抗,那么此消彼長,它會一步步成長,直到你覺得不能再逃避想要面對它時,它已經是個龐然大物,此時便會有心無力。碰到困難,最簡單也是最有效的方法,直接面對它,將它分解成你能解決的許多小塊,這就是分治算法的核心:分而治之。
總結
以上是生活随笔為你收集整理的Android--大转盘的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。