Android/安卓仿淘寶直播點贊效果/qq空間點贊效果動畫
之前玩淘寶誤入它的直播頻道,發現它的直播介面的點贊效果挺好看,然後發現QQ控制元件點贊有類似動畫,於是趁有空花了點時間玩玩。
先上個效果圖:
添加了一個按鈕模擬點贊,點選多少次就出現多個水果,他們的運動軌跡和速度是不一樣的,而且帶有淡入淡出效果。這是淘寶直播的效果,qq空間是點選一次就出現好多個的,修改一點邏輯也能實現對應的效果。
gif圖看起來有點不流暢,因為錄製時鎖定的幀率避免超2M不能上傳,實際執行是流暢的。
因為不是做成一個通用控制元件,所以我也就實現了效果,大家如果要用,可以自己加更多自定義內容。實現起來挺簡單的,也就不囉嗦了
用到的知識點:貝塞爾公式(三階)、屬性動畫、動畫集合、自動義估值器
先丟程式碼再說實現過程:
程式碼:
package cn.small_qi.transitiontest.diyview; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.TypeEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.widget.ImageView; import java.util.ArrayList; import java.util.List; import java.util.Random; import cn.small_qi.transitiontest.R; public class PressLikeView extends ViewGroup { private List<Integer> images;//圖片 private List<Interpolator> inters;//插值器 private Random random; private int defaultSize = 150;//圖片預設尺寸(px) public PressLikeView(Context context) { super(context); } public PressLikeView(Context context, AttributeSet attrs) { super(context, attrs); initData(); } //初始化資料 private void initData() { random =new Random(); images = new ArrayList<>(); inters = new ArrayList<>(); images.add(R.drawable.a510209); images.add(R.drawable.a510213); images.add(R.drawable.a510216); images.add(R.drawable.a510222); images.add(R.drawable.a510225); images.add(R.drawable.a510234); //.... inters.add(new LinearInterpolator()); inters.add(new AccelerateInterpolator()); inters.add(new AccelerateDecelerateInterpolator()); inters.add(new DecelerateInterpolator()); //.... } public PressLikeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { } //使用預置的隨機圖片 public void show(){//這個方法是開放出去的,就是按鈕點選時呼叫,出現一個水果動畫 ImageView view = new ImageView(getContext()); view.setImageResource(images.get(random.nextInt(images.size())));//隨機設定一張圖片 view.setLayoutParams(new LayoutParams(defaultSize,defaultSize));//設定大小 addView(view);//新增到容器中 view.layout(getWidth()/2-defaultSize, (int) (getHeight()-defaultSize*1.5),getWidth()/2, (int) (getHeight()-0.5*defaultSize));//計算位置 startAnim(view);//開始動畫 } //使用自定義的圖片 -- 也可以修改成傳入一個ImageView public void show(Drawable drawable){ ImageView view = new ImageView(getContext()); view.setImageDrawable(drawable); view.setLayoutParams(new LayoutParams(defaultSize,defaultSize)); addView(view); view.layout(getWidth()/2-defaultSize, (int) (getHeight()-defaultSize*1.5),getWidth()/2, (int) (getHeight()-0.5*defaultSize)); startAnim(view); } private void startAnim(final ImageView view) { AnimatorSet animatorSet = new AnimatorSet(); //淡入動畫 ValueAnimator inAnim = ValueAnimator.ofFloat(0.5f,1f); inAnim.setDuration(500); inAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float value = (float) animation.getAnimatedValue(); view.setAlpha(value); view.setScaleX(value); view.setY(value); } }); //淡出動畫 ValueAnimator outAnim = ValueAnimator.ofFloat(1,0); outAnim.setDuration(1500); outAnim.setStartDelay(1500);//延遲啟動,保證水果飛到一大半再淡出 outAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { view.setAlpha((float) animation.getAnimatedValue()); } }); //位移動畫 ValueAnimator transAnim = ValueAnimator.ofObject(new BezierValue(),new Point(getWidth()/2,getHeight()),new Point(new Random().nextInt(getWidth()),0)); transAnim.setDuration(3000); transAnim.setInterpolator(inters.get(random.nextInt(inters.size())));//隨機設定插值器 transAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Point point = (Point) animation.getAnimatedValue(); view.setX(point.x); view.setY(point.y); } }); //組合動畫 //三個動畫同時執行 animatorSet.playTogether(inAnim,transAnim,outAnim); //前面兩個動畫延遲執行,最後一個同時執行 /*animatorSet.playSequentially(inAnim,transAnim); animatorSet.play(outAnim);*/ animatorSet.start(); animatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { removeView(view);//動畫結束移除ImageView } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } //自定義插值器 class BezierValue implements TypeEvaluator<Point>{ private Random random =new Random(); private int ctrlPX1, ctrlPX2,ctrlPY1, ctrlPY2; private boolean isInit;//只需要初始化一次 @Override public Point evaluate(float fraction, Point startValue, Point endValue) { Point point = new Point(); point.x = (int) cubicPointX(fraction,startValue.x,endValue.x); point.y = (int) cubicPointY(fraction,startValue.y,endValue.y); return point; } //貝塞爾計算x private double cubicPointX(float fraction, int start, int end){ if (!isInit){ //初始化控制點y左邊 ctrlPY1 = random.nextInt(start+end/2); ctrlPY2 = random.nextInt(start+end/2)+(start+end/2); //初始化控制點x座標 if (random.nextBoolean()){//先左後右 ctrlPX1 = (int) (random.nextInt(start)-start/4f);//減去start/4 是為了運動曲線更明顯 ctrlPX2 = (int) (random.nextInt(start)+start*1.25f);//start是寬度的一半,為了保證後面往右運動,應該是隨機數加上start。現在乘1.25是為了讓曲線更明顯 }else{//先右後左 ctrlPX1 = (int) (random.nextInt(start)+start*1.25f); ctrlPX2 = (int) (random.nextInt(start)-start/4f); } isInit =true; } return start*Math.pow((1-fraction),3)+3* ctrlPX1 *fraction*Math.pow((1-fraction),2) +3* ctrlPX2 *Math.pow(fraction,2)*(1-fraction)+end*Math.pow(fraction,3); } //貝塞爾計算y private double cubicPointY(float fraction, int start, int end){ return start*Math.pow((1-fraction),3)+3* ctrlPY1 *fraction*Math.pow((1-fraction),2) +3* ctrlPY2 *Math.pow(fraction,2)*(1-fraction)+end*Math.pow(fraction,3); } } }
其實就是
1.自定義一個ViewGroup,然後每點選一次就往裡面新增一個ImageView,然後設定好它的位置和大小
2.為每一個ImageView設定隨機的圖片,然後對其執行一些列動畫
3.為了某些效果加入了淡入淡出動畫,相信大家都熟悉,根據自己需求來決定怎麼寫就行了
4.主要是運動軌跡動畫,為了路徑不是單純的直線或者簡單的曲線,所以用了自定義估值器配合三階的貝塞爾實現運動路徑
5.為了實現運動速度的不規則,內建了4種插值器,然後每次隨機取一個,用在運動軌跡的動畫上
可能有點難看懂的是我位置的計算和貝塞爾控制點的計算,我這裡簡要說明一下。
初始位置我本來是是要底部居中,但是稍微做了點偏移,計算位置如圖所示:
而貝塞爾兩個控制點和終點的選擇,我是這麼計算的,大家結合程式碼看就看得懂了:
計算好動畫之後,接下來就不難了!執行動畫就好了,這樣就實現的這種效果拉!
--本文結束,謝謝大家閱讀
相關推薦
Android/安卓仿淘寶直播點贊效果/qq空間點贊效果動畫
之前玩淘寶誤入它的直播頻道,發現它的直播介面的點贊效果挺好看,然後發現QQ控制元件點贊有類似動畫,於是趁有空花了點時間玩玩。 先上個效果圖: 添加了一個按鈕模擬點贊,點選多少次就出現多個水果,他們的運動軌跡和速度是不一樣的,而且帶有淡入淡出效果。這是淘寶直播的效果,qq
仿淘寶頁面的搜索引擎,點擊輸入框文字不消失
arch 大堆 urn images ace src func 國際 lan 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8
android 資料重構(仿淘寶瀏覽記錄,足跡)
資料結構 ->資料重構 原因 處理這個資料的主要原因是,後臺伺服器返回的資料格式在ios那邊因為其控制元件可以對資料進行分割槽顯示,可以直接處理,而在android上我們顯示控制元件就是li
Android開發之仿淘寶商品詳情頁
看到有人在問如何實現淘寶商品詳情頁效果,手癢了就擼了一個,獻上效果圖 大致梳理一下思路,這裡不提供原始碼 狀態列透明使用開源庫StatusBarCompat,為了相容手機4.4 dependencies { compile ('com.
Android 安卓 fragment+viewpager 仿qq介面 實現點選選單切換介面+滑動切換viewpager切換介面
原始碼地址 http://download.csdn.net/detail/zhangjm_123/7902245 最近寫了一個fragment+viewpager仿qq的app,先上圖 如圖,介面底部有四個textview,分別
android軟件開發之仿淘寶選擇規格的實現
per con attribute back view.gone boolean 做了 over ear 在一些app開發項目中選擇商品規格這個功能最容易遇到問題,想要實現需要的全部功能,但一直沒有成功,所以就去找了個Demo,學習界面UI采用recyclerview,it
Android開發仿淘寶商品詳情瀏覽效果 兩步曲
效果圖: 第一步佈局檔案: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/andr
Android仿淘寶底部圖示導航欄
在上一篇中,簡單的使用透明主題的Activity實現了仿微信右側頂部的對話方塊,上午又花了兩個小時研究了一下淘寶底部的導航欄實現,網上的做法也有很多,今天我就使用一種通過基本控制元件加上佈局的方式,沒有任何的自定義風格,控制元件等來實現,還是老樣子,先看一下效果
java B2B2C springmvc mybatis仿淘寶電子商城系統-整合企業架構的技術點
spring cloud本身提供的元件就很多,但我們需要按照企業的業務模式來定製企業所需要的通用架構,那我們現在需要考慮使用哪些技術呢? 下面我針對於spring cloud微服務分散式雲架構做了以下技術總結,希望可以幫助到大家: 需要JAVA Spring Cloud大型企業分散式
Android自定義控制元件實戰——仿淘寶商品瀏覽介面
用手機淘寶瀏覽商品詳情時,商品圖片是放在後面的,在第一個ScrollView滾動到最底下時會有提示,繼續拖動才能瀏覽圖片。仿照這個效果寫一個出來並不難,只要定義一個Layout管理兩個ScrollView就行了,當第一個ScrollView滑到底部時,再次向上滑動進入第二
Android 仿淘寶商品詳情標題欄變色,佈局層疊效果
如圖效果 思路:如圖可以將圖片中佈局分成三個部分,1標題欄透明背景,2上半部分佈局,3下半部分佈局,當我們向上拉動的時候,1佈局實現漸變,從透明變到白色,2佈局背景色漸變到白色,23佈局隨滾動條上拉,並且慢慢改變2佈局paddingtop的屬性,其中1佈局漂浮在整個scro
android 自定義ViewGroup實現仿淘寶的商品詳情頁
最近公司在新版本上有一個需要, 要在首頁新增一個滑動效果, 具體就是仿照X寶的商品詳情頁, 拉到頁面底部時有一個粘滯效果, 如下圖 X東的商品詳情頁,如果使用者繼續向上拉的話就進入商品圖文描述介面: 剛開始是想拿來主義,直接從網上找個現成的demo來用, 但是網上無一
Android 仿淘寶商品詳情頁下拉足跡Demo
DropDownMultiPager 仿淘寶等商品詳情頁下拉足跡效果SimpleDemo 可colne之後看MainActivity的呼叫,方便二次開發 依賴 compile 'com.nin
仿淘寶商品詳情頁面Android
1、需求: 要實現一個類似淘寶、京東的商品詳情頁面。首先是在看一些前輩的思路,檢視之後,發現博主qifengdeqingchen的文章不錯,然後去下載下來檢視demo。 2、查閱資料 來看看前輩的思路圖。使用兩個scrollView,兩個scr
android自定義ProgressBar(仿淘寶)的載入效果
三種方式實現自定義圓形頁面載入中效果的進度條 To get a ProgressBar in the default theme that is to be used on white/light back ground, use one of the inverse st
android 仿淘寶、京東商品詳情頁 向上拖動檢視圖文詳情控制元件
/** * Created by baoyunlong on 16/6/8. */ public class PullUpToLoadMore extends ViewGroup { public static String TAG = PullUpToLoadMore.class.getName
Android 小樣之高仿淘寶時間軸物流資訊
最近做訂單系統,用到時間軸資訊,首先想到的是淘寶的物流時間軸(網購狗)。不多廢話,首先來看看淘寶物流資訊的樣式 這裡給出兩種解決方法: 使用LinearLayout動態新增view生成物流資訊
Android一點 仿淘寶購物車動畫
首先看看ios上的淘寶購物車的動畫效果ios淘寶購物車動畫 我們實現的效果 看特效是分為兩個介面,一個是主view,一個是彈出層。彈出層是用dialog實現的,只是加入了彈出的動畫,這裡就不分析了,我們主要看主view的動畫是怎麼實現的,初看好像只是
Android 仿淘寶京東等我的訂單介面及任意列表拓展
概述 目前像淘寶及展示列表等都有多個item展示的需求,可能大多數如果沒做過,第一眼就是ListView去巢狀ListView,雖然這樣是可以完成,但是這樣做會導致手機過度繪製,為什麼呢?因為當一個Item載入的時候又會去更新item裡面的adapter,ap
【商城開發三】Android 仿淘寶商品詳情頁下拉足跡修改版
開發商城的快有半個月了,需要做到詳情頁下拉足跡的效果,網上找了找沒找到,找到一個差不多還有點問題,然後在基礎上進行了二次開發 感謝http://blog.csdn.net/yaphetzhao/article/details/53736471 YaphetZhao的部落格