<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了Android貝塞爾曲線實現加入購物車拋物線動畫的具體程式碼,供大家參考,具體內容如下
先上圖看效果
a.確定動畫的起終點
b.在起終點之間使用二次貝塞爾曲線填充起終點之間的點的軌跡
c.設定屬性動畫,ValueAnimator插值器,獲取中間點的座標
d.將執行動畫的控制元件的x、y座標設為上面得到的中間點座標
e.開啟屬性動畫
f.當動畫結束時的操作
獲取控制元件在螢幕中的絕對座標:
int[] parentLocation = new int[2]; mRLayout.getLocationInWindow(parentLocation);
計算開始座標和結束座標:
//開始掉落的商品的起始點:商品起始點-父佈局起始點+該商品圖片的一半 float startX = startLoc[0] - parentLocation[0] + iv.getWidth() / 2; float startY = startLoc[1] - parentLocation[1] + iv.getHeight() / 2; //商品掉落後的終點座標:購物車起始點-父佈局起始點+購物車圖片的1/5 float toX = endLoc[0] - parentLocation[0] + mCart.getWidth() / 5; float toY = endLoc[1] - parentLocation[1];
貝塞爾曲線以及屬性動畫:
Path path = new Path(); //移動到起始點(貝塞爾曲線的起點) path.moveTo(startX, startY); //使用二次薩貝爾曲線:注意第一個起始座標越大,貝塞爾曲線的橫向距離就會越大,一般按照下面的式子取即可 path.quadTo((startX + toX) / 2, startY, toX, toY); //mPathMeasure用來計算貝塞爾曲線的曲線長度和貝塞爾曲線中間插值的座標, // 如果是true,path會形成一個閉環 mPathMeasure = new PathMeasure(path, false); //屬性動畫實現(從0到貝塞爾曲線的長度之間進行插值計算,獲取中間過程的距離值) ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength()); valueAnimator.setDuration(1000); // 勻速線性插值器 valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 當插值計算進行時,獲取中間的每個值, // 這裡這個值是中間過程中的曲線長度(下面根據這個值來得出中間點的座標值) float value = (Float) animation.getAnimatedValue(); // 獲取當前點座標封裝到mCurrentPosition // boolean getPosTan(float distance, float[] pos, float[] tan) : // 傳入一個距離distance(0<=distance<=getLength()),然後會計算當前距 // 離的座標點和切線,pos會自動填充上座標,這個方法很重要。 mPathMeasure.getPosTan(value, mCurrentPosition, null);//mCurrentPosition此時就是中間距離點的座標值 // 移動的商品圖片(動畫圖片)的座標設定為該中間點的座標 goods.setTranslationX(mCurrentPosition[0]); goods.setTranslationY(mCurrentPosition[1]); } }); // 五、 開始執行動畫 valueAnimator.start(); // 六、動畫結束後的處理 valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } //當動畫結束後: @Override public void onAnimationEnd(Animator animation) { // 購物車的數量加1 i++; mCount.setText(String.valueOf(i)); // 把移動的圖片imageView從父佈局裡移除 mRLayout.removeView(goods); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } });
xml裡的寫法:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:id="@+id/rl" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加入購物車"/> <ImageView android:layout_toRightOf="@id/add" android:id="@+id/goods" android:src="@mipmap/ic_launcher" android:layout_width="50dp" android:layout_height="50dp" /> <TextView android:id="@+id/count" android:layout_marginLeft="300dp" android:layout_marginTop="70dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0"/> <ImageView android:id="@+id/cart" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginLeft="300dp" android:layout_marginTop="240dp" android:src="@drawable/ic_shopping_cart" /> </RelativeLayout> </LinearLayout>
使用了Butterknife和自己封裝的BaseActivity,要使用的話需要自行修改程式碼。
完整程式碼:
import android.animation.Animator; import android.animation.ValueAnimator; import android.graphics.Path; import android.graphics.PathMeasure; import android.view.View; import android.view.animation.LinearInterpolator; import android.widget.Button; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.xp.baseapp.R; import com.xp.baseapp.base.BaseActivity; import butterknife.BindView; import butterknife.OnClick; public class ShoppingCartAnimationActivity extends BaseActivity { @BindView(R.id.add) Button mAdd; @BindView(R.id.rl) RelativeLayout mRLayout; @BindView(R.id.count) TextView mCount; @BindView(R.id.cart) ImageView mCart; @BindView(R.id.goods) ImageView mGoods; private PathMeasure mPathMeasure; /** * 貝塞爾曲線中間過程的點的座標 */ private float[] mCurrentPosition = new float[2]; /** * 購物車中的商品數量 */ private int i = 0; @Override protected int getContentViewId() { return R.layout.activity_shopping_cart_animation; } @Override protected void init() { } @OnClick(R.id.add) public void addGood(View v) { addCart(mGoods); } /** * 把商品新增到購物車的動畫效果 * * @param iv */ private void addCart(ImageView iv) { // 一、創造出執行動畫的主題---imageview //程式碼new一個imageview,圖片資源是上面的imageview的圖片 // (這個圖片就是執行動畫的圖片,從開始位置出發,經過一個拋物線(貝塞爾曲線),移動到購物車裡) final ImageView goods = new ImageView(ShoppingCartAnimationActivity.this); goods.setImageDrawable(iv.getDrawable()); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100); mRLayout.addView(goods, params); // 二、計算動畫開始/結束點的座標的準備工作 //得到父佈局的起始點座標(用於輔助計算動畫開始/結束時的點的座標) int[] parentLocation = new int[2]; mRLayout.getLocationInWindow(parentLocation); //得到商品圖片的座標(用於計算動畫開始的座標) int startLoc[] = new int[2]; iv.getLocationInWindow(startLoc); //得到購物車圖片的座標(用於計算動畫結束後的座標) int endLoc[] = new int[2]; mCart.getLocationInWindow(endLoc); // 三、正式開始計算動畫開始/結束的座標 //開始掉落的商品的起始點:商品起始點-父佈局起始點+該商品圖片的一半 float startX = startLoc[0] - parentLocation[0] + iv.getWidth() / 2; float startY = startLoc[1] - parentLocation[1] + iv.getHeight() / 2; //商品掉落後的終點座標:購物車起始點-父佈局起始點+購物車圖片的1/5 float toX = endLoc[0] - parentLocation[0] + mCart.getWidth() / 5; float toY = endLoc[1] - parentLocation[1]; // 四、計算中間動畫的插值座標(貝塞爾曲線)(其實就是用貝塞爾曲線來完成起終點的過程) //開始繪製貝塞爾曲線 Path path = new Path(); //移動到起始點(貝塞爾曲線的起點) path.moveTo(startX, startY); //使用二次薩貝爾曲線:注意第一個起始座標越大,貝塞爾曲線的橫向距離就會越大,一般按照下面的式子取即可 path.quadTo((startX + toX) / 2, startY, toX, toY); //mPathMeasure用來計算貝塞爾曲線的曲線長度和貝塞爾曲線中間插值的座標, // 如果是true,path會形成一個閉環 mPathMeasure = new PathMeasure(path, false); //屬性動畫實現(從0到貝塞爾曲線的長度之間進行插值計算,獲取中間過程的距離值) ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength()); valueAnimator.setDuration(1000); // 勻速線性插值器 valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 當插值計算進行時,獲取中間的每個值, // 這裡這個值是中間過程中的曲線長度(下面根據這個值來得出中間點的座標值) float value = (Float) animation.getAnimatedValue(); // 獲取當前點座標封裝到mCurrentPosition // boolean getPosTan(float distance, float[] pos, float[] tan) : // 傳入一個距離distance(0<=distance<=getLength()),然後會計算當前距 // 離的座標點和切線,pos會自動填充上座標,這個方法很重要。 mPathMeasure.getPosTan(value, mCurrentPosition, null);//mCurrentPosition此時就是中間距離點的座標值 // 移動的商品圖片(動畫圖片)的座標設定為該中間點的座標 goods.setTranslationX(mCurrentPosition[0]); goods.setTranslationY(mCurrentPosition[1]); } }); // 五、 開始執行動畫 valueAnimator.start(); // 六、動畫結束後的處理 valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } //當動畫結束後: @Override public void onAnimationEnd(Animator animation) { // 購物車的數量加1 i++; mCount.setText(String.valueOf(i)); // 把移動的圖片imageView從父佈局裡移除 mRLayout.removeView(goods); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45