現(xiàn)在市面上直播類的應(yīng)用可以說是一抓一大把,隨隨便便就以什么主題來開發(fā)個直播App,說白了就想在這領(lǐng)域分杯羹。在使用這些應(yīng)用過程中其實不難發(fā)現(xiàn),在所有的直播界面,少不了的就是各種打賞、各種點贊。今天自己就針對點贊功能敲了一下,代碼不多,主要是涉及到動畫運動軌跡運算,這里需借助 貝塞爾曲線 相關(guān)知識,我使用三階貝塞爾曲線來實現(xiàn)軌跡動畫。
運行效果
一、具體實現(xiàn)流程
仔細分析整個點贊過程可以發(fā)現(xiàn),首先是“愛心”的出現(xiàn)動畫,然后是“愛心”以類似氣泡的形式向上運動。
“愛心”的出現(xiàn)動畫
1
2
3
4
5
6
7
8
9
10
|
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; } |
這里使用了屬性動畫來改變“愛心”圖片控件在屏幕上的狀態(tài),具體使用了控件透明度Alpha、控件的縮放程度 Scale 等屬性動畫。
“愛心“的上浮軌跡動畫
1
2
3
4
5
6
7
8
9
10
11
|
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; } |
這里我們需要自定義一個估值算法 CurveEveluator,因為“愛心”在上浮的過程中并不是以某一直線運動的,而是通過一條不規(guī)則的曲線往上浮,而我們知道 TypeEveluator 的作用就是根據(jù)動畫的變化率來設(shè)置控件屬性的當(dāng)前值,具體算法實現(xiàn)就是使用三階貝塞爾曲線公式:
其中 P0 是動畫的起點,P3 是動畫的終點,而另外兩點P1、P2是則作為三階貝塞爾曲線的控制點。具體P1、P2要去什么值,這個憑經(jīng)驗,感覺差不多就行哈 ^_^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
private class CurveEvaluator implements TypeEvaluator<PointF> { // 由于這里使用的是三階的貝塞兒曲線, 所以我們要定義兩個控制點 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) { // 這里運用了三階貝塞兒曲線的公式,參照上面公式 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; // 二階貝塞兒曲線,具體公式請上網(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; } } |
二、使用操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
< 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 > |
然后在點擊響應(yīng)事件中調(diào)用 FlowLikeView 實例的 addLikeView() 方法可以啦。當(dāng)然,記得在動畫結(jié)束后將 view 從容器中 remove 調(diào)哦。
源碼下載
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/Anennzxq/article/details/51635476