Android控件FlowLikeView實(shí)現(xiàn)點(diǎn)贊動(dòng)畫
現(xiàn)在市面上直播類的應(yīng)用可以說(shuō)是一抓一大把,隨隨便便就以什么主題來(lái)開發(fā)個(gè)直播App,說(shuō)白了就想在這領(lǐng)域分杯羹。在使用這些應(yīng)用過(guò)程中其實(shí)不難發(fā)現(xiàn),在所有的直播界面,少不了的就是各種打賞、各種點(diǎn)贊。今天自己就針對(duì)點(diǎn)贊功能敲了一下,代碼不多,主要是涉及到動(dòng)畫運(yùn)動(dòng)軌跡運(yùn)算,這里需借助 貝塞爾曲線 相關(guān)知識(shí),我使用三階貝塞爾曲線來(lái)實(shí)現(xiàn)軌跡動(dòng)畫。
運(yùn)行效果
一、具體實(shí)現(xiàn)流程
仔細(xì)分析整個(gè)點(diǎn)贊過(guò)程可以發(fā)現(xiàn),首先是“愛心”的出現(xiàn)動(dòng)畫,然后是“愛心”以類似氣泡的形式向上運(yùn)動(dòng)。
“愛心”的出現(xiàn)動(dòng)畫
private AnimatorSet generateEnterAnimation(View target) { ObjectAnimator alpha = ObjectAnimator.ofFloat(target, "alpha", 0.2f, 1f); ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, "scaleX", 0.5f, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, "scaleY", 0.5f, 1f); AnimatorSet enterAnimation = new AnimatorSet(); enterAnimation.playTogether(alpha, scaleX, scaleY); enterAnimation.setDuration(150); enterAnimation.setTarget(target); return enterAnimation; }
這里使用了屬性動(dòng)畫來(lái)改變“愛心”圖片控件在屏幕上的狀態(tài),具體使用了控件透明度Alpha、控件的縮放程度 Scale 等屬性動(dòng)畫。
“愛心“的上浮軌跡動(dòng)畫
private ValueAnimator generateCurveAnimation(View target) { CurveEvaluator evaluator = new CurveEvaluator(generateCTRLPointF(1), generateCTRLPointF(2)); ValueAnimator valueAnimator = ValueAnimator.ofObject(evaluator, new PointF((mViewWidth - mPicWidth) / 2, mViewHeight - mChildViewHeight - mPicHeight), new PointF((mViewWidth) / 2 + (mRandom.nextBoolean() ? 1 : -1) * mRandom.nextInt(100), 0)); valueAnimator.setDuration(3000); valueAnimator.addUpdateListener(new CurveUpdateLister(target)); valueAnimator.setTarget(target); return valueAnimator; }
這里我們需要自定義一個(gè)估值算法 CurveEveluator,因?yàn)椤皭坌摹痹谏细〉倪^(guò)程中并不是以某一直線運(yùn)動(dòng)的,而是通過(guò)一條不規(guī)則的曲線往上浮,而我們知道 TypeEveluator 的作用就是根據(jù)動(dòng)畫的變化率來(lái)設(shè)置控件屬性的當(dāng)前值,具體算法實(shí)現(xiàn)就是使用三階貝塞爾曲線公式:
其中 P0 是動(dòng)畫的起點(diǎn),P3 是動(dòng)畫的終點(diǎn),而另外兩點(diǎn)P1、P2是則作為三階貝塞爾曲線的控制點(diǎn)。具體P1、P2要去什么值,這個(gè)憑經(jīng)驗(yàn),感覺差不多就行哈 ^_^
private class CurveEvaluator implements TypeEvaluator<PointF> { // 由于這里使用的是三階的貝塞兒曲線, 所以我們要定義兩個(gè)控制點(diǎn) private PointF ctrlPointF1; private PointF ctrlPointF2; public CurveEvaluator(PointF ctrlPointF1, PointF ctrlPointF2) { this.ctrlPointF1 = ctrlPointF1; this.ctrlPointF2 = ctrlPointF2; } @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { // 這里運(yùn)用了三階貝塞兒曲線的公式,參照上面公式 float leftTime = 1.0f - fraction; PointF resultPointF = new PointF(); // 三階貝塞兒曲線 resultPointF.x = (float) Math.pow(leftTime, 3) * startValue.x + 3 * (float) Math.pow(leftTime, 2) * fraction * ctrlPointF1.x + 3 * leftTime * (float) Math.pow(fraction, 2) * ctrlPointF2.x + (float) Math.pow(fraction, 3) * endValue.x; resultPointF.y = (float) Math.pow(leftTime, 3) * startValue.y + 3 * (float) Math.pow(leftTime, 2) * fraction * ctrlPointF1.y + 3 * leftTime * fraction * fraction * ctrlPointF2.y + (float) Math.pow(fraction, 3) * endValue.y; // 二階貝塞兒曲線,具體公式請(qǐng)上網(wǎng)查閱 // resultPointF.x = (float) Math.pow(leftTime, 2) * startValue.x + 2 * fraction * leftTime * ctrlPointF1.x // + ((float) Math.pow(fraction, 2)) * endValue.x; // resultPointF.y = (float) Math.pow(leftTime, 2) * startValue.y + 2 * fraction * leftTime * ctrlPointF1.y // + ((float) Math.pow(fraction, 2)) * endValue.y; return resultPointF; } }
二、使用操作
<com.anenn.flowlikeviewlib.FlowLikeView android:id="@+id/flowLikeView" android:layout_width="75dp" android:layout_height="200dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@android:color/transparent" android:includeFontPadding="false" android:onClick="addLikeView" android:text="Like" android:textColor="#0099cc" android:textSize="18sp" android:textStyle="bold" /> </com.anenn.flowlikeviewlib.FlowLikeView>
然后在點(diǎn)擊響應(yīng)事件中調(diào)用 FlowLikeView 實(shí)例的 addLikeView() 方法可以啦。當(dāng)然,記得在動(dòng)畫結(jié)束后將 view 從容器中 remove 調(diào)哦。
源碼下載
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android ScrollView 下嵌套 ListView 或 GridView出現(xiàn)問(wèn)題解決辦法
這篇文章主要介紹了ScrollView 下嵌套 ListView 或 GridView 會(huì)發(fā)列表現(xiàn)數(shù)據(jù)只能顯示一行。因?yàn)樗麄兌际菨L動(dòng)結(jié)構(gòu),兩個(gè)滾動(dòng)條放到一起就會(huì)引起沖突,這里提供解決辦法相關(guān)資料,需要的朋友可以參考下2017-07-07Android?studio開發(fā)實(shí)現(xiàn)計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了Android?studio開發(fā)實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Android 后臺(tái)生成長(zhǎng)圖并分享示例(非長(zhǎng)截圖)
這篇文章主要介紹了Android 后臺(tái)生成長(zhǎng)圖并分享示例(非長(zhǎng)截圖),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08Android Flutter基于WebSocket實(shí)現(xiàn)即時(shí)通訊功能
WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。本文將利用Flutter WebSocket實(shí)現(xiàn)即時(shí)通訊功能,文中示例代碼講解詳細(xì),感興趣的可以了解一下2022-03-03Flutter定時(shí)器、倒計(jì)時(shí)的快速上手及實(shí)戰(zhàn)講解
這篇文章主要給大家介紹了關(guān)于Flutter定時(shí)器、倒計(jì)時(shí)的快速上手及實(shí)戰(zhàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06Android高德地圖poi檢索仿微信發(fā)送位置實(shí)例代碼
本篇文章主要介紹了Android高德地圖poi檢索仿微信發(fā)送位置實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04Android Studio時(shí)間選擇器的創(chuàng)建方法
這篇文章主要為大家詳細(xì)介紹了Android Studio時(shí)間選擇器的創(chuàng)建方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10