android仿即刻點(diǎn)贊文字部分的自定義View的示例代碼
概述:在學(xué)習(xí)HenCoder的過(guò)程中,有一期是模仿優(yōu)秀自定義View,有一個(gè)項(xiàng)目是仿即刻的點(diǎn)贊,后來(lái)原作者在點(diǎn)評(píng)中提到,需要將文字和圖片分開(kāi)來(lái)寫(xiě),并且模仿者的動(dòng)畫(huà)實(shí)現(xiàn)由點(diǎn)雜亂。所以決定重現(xiàn)實(shí)現(xiàn)下文字部分的效果。并拓展了更多功能。最后說(shuō)一句本文基于kotlin實(shí)現(xiàn)。不明白的地方請(qǐng)?jiān)谠u(píng)論區(qū)指出。
即刻原效果:個(gè)人效果:
分析
從效果圖容易看出,圖中的功能主要分為兩個(gè)部分:
- 左側(cè)大拇指動(dòng)畫(huà)
- 右側(cè)的文字動(dòng)畫(huà)
拓展的功能包括:文字變換模式(全部和部分) 改變文字和未改變文字的間隔和顏色,文字始終位于中心位置。
一 文字的繪制
對(duì)文字繪制還不熟悉的同學(xué)請(qǐng)參考HenCoder系列文章,這里只對(duì)怎么實(shí)現(xiàn)居中的作一下說(shuō)明。
1 水平居中
水平居中的繪制按文字變換模式分為兩種
全部改變時(shí):
控件寬度的一半減去文字寬度的一半 即是文字開(kāi)始繪制的位置
canvas.drawText(array[1], width / 2.toFloat() - halfTextWidth(array[1]), baseLineY + yOffset, mPaint) canvas.drawText(array[2], width / 2.toFloat() - halfTextWidth(array[2]), baseLineY + height / 2 + +halfOfTextHeight + yOffset, mPaint)
部分改變時(shí)
計(jì)算每部分文字起始位置
// 獲取部分改變的模式時(shí)的繪制文字其實(shí)起始位置 startX = width / 2.toFloat() - (2 * halfTextWidth(array[0]) + mTextSpace + 2 * halfTextWidth(array[1])) / 2 mPaint.color = mNoChangeTextColor canvas.drawText(array[0], startX, baseLineY, mPaint) mPaint.color = mChangedTextColor canvas.drawText(array[1], startX + 2 * halfTextWidth(array[0]) + mTextSpace, baseLineY + yOffset, mPaint) canvas.drawText(array[2], startX + 2 * halfTextWidth(array[0]) + mTextSpace, baseLineY + height / 2 + +halfOfTextHeight + yOffset, mPaint)
2 垂直居中
垂直居中的實(shí)現(xiàn),最重要的是需要計(jì)算文字基線在垂直方向的位置 計(jì)算公式就不在這里解釋了
var fontMetrics = mPaint.fontMetrics // 文字基線y軸坐標(biāo) 為了 讓文字 垂直居中 val baseLineY = height / 2 - fontMetrics.top / 2 - fontMetrics.bottom / 2
二 動(dòng)畫(huà)的實(shí)現(xiàn)
可以看到 我們默認(rèn)是沒(méi)有點(diǎn)贊的,然后點(diǎn)一下就贊,再點(diǎn)一下 取消點(diǎn)贊。所以思路是這樣的 首先繪制居中文字,然后在控件看不到的下方再繪制一遍,然后根據(jù)平移動(dòng)畫(huà)完成這個(gè)效果,這個(gè)動(dòng)畫(huà)是通過(guò)屬性動(dòng)畫(huà)實(shí)現(xiàn)的。
// 為了顯示效果 根據(jù)是否是全部改變 設(shè)置不同的繪制方式 if (mChangeMode === 0) { mPaint.color = mChangedTextColor canvas.drawText(array[1], width / 2.toFloat() - halfTextWidth(array[1]), baseLineY + yOffset, mPaint) canvas.drawText(array[2], width / 2.toFloat() - halfTextWidth(array[2]), baseLineY + height / 2 + +halfOfTextHeight + yOffset, mPaint) } else if (mChangeMode === 1) { / 獲取部分改變的模式時(shí)的繪制文字其實(shí)起始位置 startX = width / 2.toFloat() - (2 * halfTextWidth(array[0]) + mTextSpace + 2 * halfTextWidth(array[1])) / 2 mPaint.color = mNoChangeTextColor canvas.drawText(array[0], startX, baseLineY, mPaint) mPaint.color = mChangedTextColor canvas.drawText(array[1], startX + 2 * halfTextWidth(array[0]) + mTextSpace, baseLineY + yOffset, mPaint) canvas.drawText(array[2], startX + 2 * halfTextWidth(array[0]) + mTextSpace, baseLineY + height / 2 + +halfOfTextHeight + yOffset, mPaint) }
可以看到 在設(shè)置繪制垂直方向的位置的時(shí)候,都加入了一個(gè) yOffset 的變量,通過(guò)改變這個(gè)屬性的值也顯示動(dòng)畫(huà),那個(gè)這個(gè)值的最大值很明顯就是 文字高度的一半加上控件高度的一半。
halfOfTextHeight = (fontMetrics.bottom - fontMetrics.top) / 2 textOffset = (halfOfTextHeight + height / 2)
自定義屬性動(dòng)畫(huà)必須添加的 set get 方法
@Suppress("unused") fun setYOffset(yOffset: Float) { this.yOffset = yOffset invalidate() } @Suppress("unused") fun getYOffset() = yOffset
最后提供給外界跳用的方法
fun show() { hasThumbs = if (hasThumbs) { val animator = ObjectAnimator.ofFloat(this, "yOffset", -textOffset, 0f) animator.duration = 500 animator.start() false } else { val animator = ObjectAnimator.ofFloat(this, "yOffset", 0f, -textOffset) animator.duration = 500 animator.start() true } } // 調(diào)用 val tv: ThumbsView = findViewById(R.id.thumbsView1) as ThumbsView tv.show()
三 源碼
github地址:源碼點(diǎn)我直達(dá)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)朋友圈點(diǎn)贊列表
- Android自定義ViewGroup實(shí)現(xiàn)堆疊頭像的點(diǎn)贊Layout
- Android中使用PopupWindow 仿微信點(diǎn)贊和評(píng)論彈出
- Android實(shí)現(xiàn)點(diǎn)贊動(dòng)畫(huà)(27)
- Android PraiseTextView實(shí)現(xiàn)朋友圈點(diǎn)贊功能
- Android listview點(diǎn)贊問(wèn)題分析
- Android 仿微信朋友圈點(diǎn)贊和評(píng)論彈出框功能
- Android Listview點(diǎn)贊問(wèn)題關(guān)于圖片重復(fù)問(wèn)題
- Android中Listview點(diǎn)贊功能的實(shí)現(xiàn)
相關(guān)文章
android針對(duì)json數(shù)據(jù)解析方法實(shí)例分析
這篇文章主要介紹了android針對(duì)json數(shù)據(jù)解析方法,以實(shí)例形式較為詳細(xì)的分析了Android操作json格式數(shù)據(jù)的各種常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10android studio更新gradle錯(cuò)誤構(gòu)建項(xiàng)目失敗的解決方法
這篇文章主要介紹了android studio更新gradle錯(cuò)誤構(gòu)建項(xiàng)目失敗的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03Android實(shí)現(xiàn)簡(jiǎn)單的照相功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)單的照相功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03android實(shí)現(xiàn)搜索功能并將搜索結(jié)果保存到SQLite中(實(shí)例代碼)
這篇文章主要介紹了android實(shí)現(xiàn)搜索功能并將搜索結(jié)果保存到SQLite中,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Android判斷11位手機(jī)號(hào)碼的方法(正則表達(dá)式)
項(xiàng)目里頭需要做一個(gè)判斷用戶輸入的號(hào)碼是否是正確的手機(jī)號(hào)碼,正確的手機(jī)號(hào)碼應(yīng)該是11位的,這里我們需要用一個(gè)正則表達(dá)式來(lái)進(jìn)行判斷,下面我把寫(xiě)法分享給大家2016-12-12Android自動(dòng)測(cè)試工具M(jìn)onkey的實(shí)現(xiàn)方法
本文主要介紹Android Monkey 實(shí)現(xiàn)方法,Monkey測(cè)試是一種為了測(cè)試軟件的穩(wěn)定性、健壯性的快速有效的方法,具有非常重要的參考價(jià)值,希望對(duì)小伙伴有所幫助2016-07-07Android中通過(guò)view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法
這篇文章主要介紹了Android中通過(guò)view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法,本文方法相對(duì)簡(jiǎn)單,容易理解,需要的朋友可以參考下2014-09-09