生活随笔
收集整理的這篇文章主要介紹了
Android 仿直播特效点赞飘爱心
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、概述,最后面有完整代碼下載地址
老規矩先上圖
好了,基本就是這個樣子,錄完的視頻用格式工廠轉換完就這個樣子了,將就看吧
二、定義我們自己的Layout
[java]?view plaincopy
???????public?class?LoveLayout?extends?RelativeLayout{????????private?Context?context;??????private?LayoutParams?params;??????private?Drawable[]?icons?=?new?Drawable[4];??????private?Interpolator[]?interpolators?=?new?Interpolator[4];??????private?int?mWidth;??????private?int?mHeight;????????????public?LoveLayout(Context?context,?AttributeSet?attrs)?{??????????super(context,?attrs);????????????????????this.context?=?context;??????????initView();??????}????????private?void?initView()?{??????????????????????????????icons[0]?=?getResources().getDrawable(R.drawable.green);??????????icons[1]?=?getResources().getDrawable(R.drawable.purple);??????????icons[2]?=?getResources().getDrawable(R.drawable.red);??????????icons[3]?=?getResources().getDrawable(R.drawable.yellow);??????????????????????????????interpolators[0]?=?new?AccelerateDecelerateInterpolator();???????????interpolators[1]?=?new?AccelerateInterpolator();????????????interpolators[2]?=?new?DecelerateInterpolator();???????????interpolators[3]?=?new?LinearInterpolator();??????????????????????int?width?=?icons[0].getIntrinsicWidth();??????????int?height?=?icons[0].getIntrinsicWidth();??????????params?=?new?LayoutParams(width,?height);??????????params.addRule(CENTER_HORIZONTAL,?TRUE);??????????params.addRule(ALIGN_PARENT_BOTTOM,?TRUE);??????}??
基本就是做了初始化,聲明了4個drawable,也就是4個顏色的心,4個插值器,用于控制動畫速率的改變,設置初始位置為屏幕的下邊中點處。
[java]?view plaincopy
@Override??protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{????????????super.onMeasure(widthMeasureSpec,?heightMeasureSpec);??????mWidth?=?getMeasuredWidth();??????mHeight?=?getMeasuredHeight();??}????????public?void?addLoveView()?{????????????final?ImageView?iv?=?new?ImageView(context);??????iv.setLayoutParams(params);??????iv.setImageDrawable(icons[new?Random().nextInt(4)]);??????addView(iv);??????????????????????AnimatorSet?set?=?getAnimatorSet(iv);??????set.start();??????set.addListener(new?AnimatorListenerAdapter()?{??????????@Override??????????public?void?onAnimationEnd(Animator?animation)?{????????????????????????????super.onAnimationEnd(animation);??????????????removeView(iv);??????????}??????});??}??
用于添加心型效果。動畫結束后,再移除
[java]?view plaincopy
?????private?AnimatorSet?getAnimatorSet(ImageView?iv)?{??????????????????????ObjectAnimator?alpha?=?ObjectAnimator.ofFloat(iv,?"alpha",?0.3f,?1f);??????????????????????ObjectAnimator?scaleX?=?ObjectAnimator.ofFloat(iv,?"scaleX",?0.2f,?1f);??????ObjectAnimator?scaleY?=?ObjectAnimator.ofFloat(iv,?"scaleY",?0.2f,?1f);??????????????????????AnimatorSet?set?=?new?AnimatorSet();??????set.playTogether(alpha,?scaleX,?scaleY);??????set.setDuration(500);??????????????????????ValueAnimator?bzier?=?getBzierAnimator(iv);????????????????AnimatorSet?set2?=?new?AnimatorSet();??????set2.playSequentially(set,?bzier);??????set2.setTarget(iv);??????return?set2;??}??
playTogether:幾個動畫同時執行
ObjectAnimator為屬性動畫,不熟悉可以百度了解下
然后是設置貝塞爾曲線動畫
playSequentially:動畫依次執行
[java]?view plaincopy
????private?ValueAnimator?getBzierAnimator(final?ImageView?iv)?{????????????????PointF[]?PointFs?=?getPointFs(iv);???????BasEvaluator?evaluator?=?new?BasEvaluator(PointFs[1],?PointFs[2]);??????ValueAnimator?valueAnim?=?ValueAnimator.ofObject(evaluator,?PointFs[0],?PointFs[3]);??????valueAnim.addUpdateListener(new?AnimatorUpdateListener()?{????????????????????????@Override??????????public?void?onAnimationUpdate(ValueAnimator?animation)?{????????????????????????????PointF?p?=?(PointF)?animation.getAnimatedValue();??????????????iv.setX(p.x);??????????????iv.setY(p.y);??????????????iv.setAlpha(1-?animation.getAnimatedFraction());???????????}??????});??????valueAnim.setTarget(iv);??????valueAnim.setDuration(3000);??????valueAnim.setInterpolator(interpolators[new?Random().nextInt(4)]);??????return?valueAnim;??}????private?PointF[]?getPointFs(ImageView?iv)?{????????????PointF[]?PointFs?=?new?PointF[4];??????PointFs[0]?=?new?PointF();???????PointFs[0].x?=?(mWidth-?params.width)/?2;??????PointFs[0].y?=?mHeight?-?params.height;????????????PointFs[1]?=?new?PointF();???????PointFs[1].x?=?new?Random().nextInt(mWidth);????????PointFs[1].y?=?new?Random().nextInt(mHeight?/2)?+?mHeight?/?2?+?params.height;????????????PointFs[2]?=?new?PointF();???????PointFs[2].x?=?new?Random().nextInt(mWidth);????????PointFs[2].y?=?new?Random().nextInt(mHeight?/2);????????????????PointFs[3]?=?new?PointF();???????PointFs[3].x?=?new?Random().nextInt(mWidth);????????PointFs[3].y?=?0;??????return?PointFs;??}??
先獲得4個點的坐標
p0坐標:x坐標((布局的寬-心形圖片寬)除以2),y坐標(布局的高 -心形圖片高),這樣獲得的是頂部部水平中心點的坐標。
p1坐標:x坐標(橫坐標中的隨機位置),y坐標(布局一半的高度 加上 0到一半高度范圍內的隨機坐標+心形的高度的一半)。這樣取到的橫坐標是在布局寬度之內的隨機坐標,縱坐標為整個路徑高度中部以上的隨機坐標。
p2坐標:與p1類似,橫坐標是在布局寬度之內的隨機坐標,縱坐標為整個路徑高度中部以下的隨機坐標。
p3坐標:控件底部中心點
好了知道4個坐標了,那么開始計算路徑
首先為了計算貝塞爾曲線,我們先寫一個估值器
[java]?view plaincopy
???????public?class?BasEvaluator?implements?TypeEvaluator<PointF>?{????????private?PointF?p1;??????private?PointF?p2;????????public?BasEvaluator(PointF?p1,?PointF?p2)?{??????????super();??????????this.p1?=?p1;??????????this.p2?=?p2;??????}????????@Override??????public?PointF?evaluate(float?fraction,?PointF?p0,?PointF?p3)?{????????????????????PointF?pointf?=?new?PointF();??????????????????????????????pointf.x?=?p0.x?*?(1-fraction)?*(1-fraction?)?*?(1-fraction)?????????????????????+3*p1.x?*?fraction?*(1-fraction?)*(1-fraction?)?????????????????????+3*p2.x?*fraction??*fraction??*(1-fraction?)?????????????????????+p3.x*fraction?*fraction?*fraction?;???????????pointf.y?=?p0.y?*?(1-fraction?)?*(1-fraction?)?*?(1-fraction?)??????????????????+3*p1.y?*?fraction?*(1-fraction?)*(1-fraction?)??????????????????+3*p2.y?*fraction??*fraction??*(1-fraction?)??????????????????+p3.y*fraction?*fraction?*fraction?;???????????return?pointf;??????}??}??
TypeEvaluator:估值器回調evaluate方法,用于動態的改變動畫的屬性值。
evaluate三個參數:
1.fraction,默認傳入的就是(currentTime - startTime) / duration,動畫執行的時間除以總的時間比值,可以理解為變化率。當duration到了的時候,正好,起始點變到終點。
2.起始點
3.終點
根據三個參數,計算點的根據每毫秒的變化率,計算點的路徑軌跡。
好了貝塞爾曲線動畫就講完了,然后再把動畫綁定到控件上。
最后在MainActivity中根據點擊事件,進行增加心型就好了。
[java]?view plaincopy
btn_press?=?(Button)findViewById(R.id.btn_press);??ll_love?=?(LoveLayout)findViewById(R.id.ll_love);??btn_press.setOnClickListener(new?OnClickListener()?{????????????????????@Override??????public?void?onClick(View?v)?{????????????????????ll_love.addLoveView();??????}??});??
完整Demo代碼下載地址:Android仿某直播點贊飄愛心
總結
以上是生活随笔為你收集整理的Android 仿直播特效点赞飘爱心的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。