分段進(jìn)度條&分段圖標(biāo)抖動動畫的實現(xiàn)

分段進(jìn)度條&分段圖標(biāo)抖動動畫的實現(xiàn)

先上圖银觅,https://github.com/Warkey1991/Jackview覺得有用的話榆俺,希望給個star


?該自定義View有三個問題需要一一實現(xiàn)

1. **如何實現(xiàn)分段** 趴梢,

2. **如何用canvas 實現(xiàn)抖動的動畫效果**

3. **如何識別點(diǎn)擊區(qū)域的點(diǎn)擊事件**

?以下就針對三個問題提供解決思路和實戰(zhàn)代碼

a.本例中采用的是均分三段,定義一個數(shù)組A = {3,5,8},再將每一段根據(jù)A 中的A[i]的值均分藐鹤,

如圖


繪制進(jìn)度的時候,需要先找出當(dāng)前進(jìn)度progress 所在的區(qū)間赂韵,然后分段繪制娱节。具體代碼如下:

```kotlin

//查找所在區(qū)間的索引

private fun findRange(): Int {

? ? if (progress >= segments.last().progress) {

? ? ? ? progressPadding = 0

? ? ? ? return segments.size - 1

? ? }

? ? var index = 0

? ? for (i in 0 until segments.size - 1) {

? ? ? ? if (progress in segments[i].progress..segments[i + 1].progress) {

? ? ? ? ? ? index = i + 1

? ? ? ? }

? ? }

? ? if (index >= 1) {

? ? ? ? currentSegmentProgress = progress - segments[index - 1].progress

? ? }

? ? return index

}

//繪制

? override fun onDraw(canvas: Canvas?) {

? ? ? ? super.onDraw(canvas)

? ? ? ? rect.set(0f, (height / 2 - dip2px(5f)).toFloat(), width.toFloat(), (height / 2 + dip2px(5f)).toFloat())

? ? ? ? canvas?.drawRoundRect(rect, horizontalRound, horizontalRound, bgPaint)

? ? ? ? val index = findRange()

? ? ? ? var eachWidth = (width - lightBitmap.width) / segments.size

? ? ? ? if (index == segments.size - 1) {

? ? ? ? ? ? eachWidth = width / segments.size

? ? ? ? }

? ? ? ? //轉(zhuǎn)為float,可以預(yù)防divide by zero 的異常

? ? ? ? val smallEachWidth = eachWidth.toFloat() / segmentMaxs[index].toFloat()

? ? ? ? var x = eachWidth * index + smallEachWidth * currentSegmentProgress

? ? ? ? x = x.coerceAtMost(width.toFloat())

? ? ? ? rect.right = x

? ? ? ? canvas?.drawRoundRect(rect, horizontalRound, horizontalRound, progressPaint)

? ? ? ? drawBitmaps(canvas)

? ? }

```

b.用canvas 實現(xiàn)抖動的動畫效果:

? 分析了單獨(dú)的View用rotate 動畫實現(xiàn)的方式,可以得出結(jié)論祭示,只需要每次繪制的時候旋轉(zhuǎn)canvas畫布即可肄满,每次旋轉(zhuǎn)的弧度需要自己自行定義,本例中使用的是`listOf(-5.0f, -4f, -3f, -2f, -1f, 2f, 3f, 4f, 5f,

? ? ? ? ? ? -5.0f, -4f, -3f, -2f, -1f, 2f, 3f, 4f, 5f,

? ? ? ? ? ? -5.0f, -4f, -3f, -2f, -1f, 2f, 3f, 4f, 5f,

? ? ? ? ? ? 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,

? ? ? ? ? ? 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,

? ? ? ? ? ? 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f)`

抖動三次停頓一會的效果,定義一個數(shù)組的索引index = 0, 從0 開始稠歉,開啟一個線程掰担,每16ms,index+1,重新繪制即可實現(xiàn),

代碼如下:

```kotlin

private fun rotate() {

? ? ? ? thread {

? ? ? ? ? ? while (!needStopThread) {

? ? ? ? ? ? ? ? if (animCount == rotateAngle.size) {

? ? ? ? ? ? ? ? ? ? animCount = 0

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? Thread.sleep(16)

? ? ? ? ? ? ? ? post {

? ? ? ? ? ? ? ? ? ? invalidate()

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? animCount++

? ? ? ? ? ? }

? ? ? ? }

? ? }

```

繪制核心代碼:

```kotlin

//獲取旋轉(zhuǎn)的弧度

val degrees = rotateAngle[animCount % rotateAngle.size]

canvas?.save()

//以中心點(diǎn)旋轉(zhuǎn)

canvas?.rotate(degrees, rectF.centerX(), rectF.centerY())

canvas?.drawBitmap(imageBitmap, null, innerRectF, null)

canvas?.restore()

```

c. 添加點(diǎn)擊區(qū)域的點(diǎn)擊事件:

三個紅色節(jié)點(diǎn)的坐標(biāo)位置在繪制的時候需要保存起來`? ? private var touchCallBackRectF = mutableListOf<RectF>()`,定義一個變量用于保存節(jié)點(diǎn)的區(qū)域位置信息怒炸。

復(fù)寫onTouchEvent 方法带饱,在MotionEvent.ACTION_UP 中判斷該點(diǎn)擊的位置是否在touchCallBackRectF 中,找出對應(yīng)的位置阅羹。

```kotlin

@SuppressLint("ClickableViewAccessibility")

? ? override fun onTouchEvent(event: MotionEvent?): Boolean {

? ? ? ? when (event?.action) {

? ? ? ? ? ? MotionEvent.ACTION_UP -> {

? ? ? ? ? ? ? ? val x = event.x

? ? ? ? ? ? ? ? val y = event.y

? ? ? ? ? ? ? ? for (i in 0 until touchCallBackRectF.size) {

? ? ? ? ? ? ? ? ? ? if (touchCallBackRectF[i].contains(x, y)) {

? ? ? ? ? ? ? ? ? ? ? ? segments[i].status = BoxStatus.AVAILABLE.ordinal

? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(context, "click index:${i}", Toast.LENGTH_SHORT).show()

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return true

? ? }

```

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勺疼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子捏鱼,更是在濱河造成了極大的恐慌执庐,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件导梆,死亡現(xiàn)場離奇詭異轨淌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)看尼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門猿诸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人狡忙,你說我怎么就攤上這事梳虽。” “怎么了灾茁?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵窜觉,是天一觀的道長。 經(jīng)常有香客問我北专,道長禀挫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任拓颓,我火速辦了婚禮语婴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驶睦。我一直安慰自己砰左,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布场航。 她就那樣靜靜地躺著缠导,像睡著了一般。 火紅的嫁衣襯著肌膚如雪溉痢。 梳的紋絲不亂的頭發(fā)上僻造,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天憋他,我揣著相機(jī)與錄音,去河邊找鬼髓削。 笑死竹挡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的立膛。 我是一名探鬼主播揪罕,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼旧巾!你這毒婦竟也來了耸序?” 一聲冷哼從身側(cè)響起忍些,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鲁猩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后罢坝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廓握,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年嘁酿,在試婚紗的時候發(fā)現(xiàn)自己被綠了隙券。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡闹司,死狀恐怖娱仔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情游桩,我是刑警寧澤牲迫,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站借卧,受9級特大地震影響盹憎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铐刘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一陪每、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧镰吵,春花似錦檩禾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至画株,卻和暖如春辆飘,著一層夾襖步出監(jiān)牢的瞬間啦辐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工蜈项, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芹关,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓紧卒,卻偏偏與公主長得像侥衬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子跑芳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359