国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android利用二階貝塞爾曲線實現添加購物車動畫詳解

2019-10-21 21:41:49
字體:
來源:轉載
供稿:網友

一、引入

  1. 其實之前一直以為像餓了么或者是美團外賣那種把商品添加到購物車的動畫會很難做,但是實際做起來好像并沒有想象中的那么難哈哈。
  2. 布局主要使用CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+TabLayout+ViewPager
  3. 動畫主要使用二階貝塞爾曲線與屬性動畫
  4. 消息傳遞使用EventBus普通事件

Android,二階貝塞爾曲線,購物車,動畫

二、大致思路

Android,二階貝塞爾曲線,購物車,動畫

1、如圖所示主要有三個點,起點、終點、以及貝塞爾曲線的控制點

2、起點即點擊的View的位置,一般來說用如下方式即可取得。startPosition[0]為x軸開始坐標,startPosition[1]為Y軸終點坐標,兩點可以看作對角線上面的兩個端點(左上角x坐標,右下角y坐標)

//貝塞爾起始數據點int[] startPosition = new int[2];view.getLocationOnScreen(startPosition);

3、終點即購物車籃子的位置,與起點類似

mShoppingCart.getLocationInWindow(endPosition);

4、控制點,我選的控制點為上圖的C點,即A點的y坐標,B點的X坐標

controlPosition[0] = endPosition[0];controlPosition[1] = startPosition[1];

5、需要注意的地方,我不清楚是不是因為我的布局的問題,獲取到的點擊的A點總是會有一個偏移,后來經同事提醒,減去了TabLayout的坐標的y軸坐標即位置才可以。

// 起點int[] startPosition;// 終點int[] endPosition = new int[2];// 貝塞爾控制點int[] controlPosition = new int[2];// tablayout位置int[] tablayoutPosition = new int[2];startPosition = data.getStartPosition();mShoppingCart.getLocationInWindow(endPosition);mTabLayout.getLocationInWindow(tablayoutPosition);// 處理起點y坐標偏移的問題startPosition[1] = startPosition[1] - tablayoutPosition[1] - mTabLayout.getHeight();// 終點進行一下居中處理endPosition[0] = endPosition[0] + (mShoppingCart.getWidth() / 2);controlPosition[0] = endPosition[0];controlPosition[1] = startPosition[1];

6、通過Path的quadTo方法繪制貝塞爾曲線,使用PathMeasure獲取點的坐標(借助ValueAnimator.ofFloat()配合getPosTan()來獲取坐標)

Path path = new Path();path.moveTo(startPosition[0], startPosition[1]);path.quadTo(controlPosition[0], controlPosition[1], endPosition[0], endPosition[1]);PathMeasure pathMeasure = new PathMeasure();// false表示path路徑不閉合pathMeasure.setPath(path, false);// ofFloat是一個生成器ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, pathMeasure.getLength());// 勻速線性插值器valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.setDuration(800);valueAnimator.addUpdateListener(animation -> { float value = (Float) animation.getAnimatedValue(); pathMeasure.getPosTan(value, currentPosition, null); imageView.setX(currentPosition[0]); imageView.setY(currentPosition[1]);});valueAnimator.start();

7、下面是用屬性動畫給購物車籃子做了一個放大縮小的動畫效果

// mShoppingCart是ViewObjectAnimator shoppingCartX = ObjectAnimator.ofFloat(mShoppingCart, "scaleX", 1.0f, 1.3f, 1.0f);ObjectAnimator shoppingCartY = ObjectAnimator.ofFloat(mShoppingCart, "scaleY", 1.0f, 1.3f, 1.0f);shoppingCartX.setInterpolator(new AccelerateInterpolator());shoppingCartY.setInterpolator(new AccelerateInterpolator());AnimatorSet shoppingCart = new AnimatorSet();shoppingCart .play(shoppingCartX) .with(shoppingCartY);shoppingCart.setDuration(800);shoppingCart.start();

三、稍完整的大部分代碼

private void AddAnimation(AddEventBean data) { // 起點 int[] startPosition; // 終點 int[] endPosition = new int[2]; // 貝塞爾控制點 int[] controlPosition = new int[2]; // 當前位置 float[] currentPosition = new float[2]; // tablayout位置 int[] tablayoutPosition = new int[2]; startPosition = data.getStartPosition(); mShoppingCart.getLocationInWindow(endPosition); mTabLayout.getLocationInWindow(tablayoutPosition); // 處理起點y坐標偏移的問題 startPosition[1] = startPosition[1] - tablayoutPosition[1] - mTabLayout.getHeight(); // 終點進行一下居中處理 endPosition[0] = endPosition[0] + (mShoppingCart.getWidth() / 2); controlPosition[0] = endPosition[0]; controlPosition[1] = startPosition[1]; final ImageView imageView = new ImageView(this); mConView.addView(imageView); imageView.setImageResource(R.drawable.specialadd); imageView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.dp_px_30); imageView.getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.dp_px_30); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setVisibility(View.VISIBLE); imageView.setX(startPosition[0]); imageView.setY(startPosition[1]); Path path = new Path(); path.moveTo(startPosition[0], startPosition[1]); path.quadTo(controlPosition[0], controlPosition[1], endPosition[0], endPosition[1]); PathMeasure pathMeasure = new PathMeasure(); // false表示path路徑不閉合 pathMeasure.setPath(path, false); // ofFloat是一個生成器 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, pathMeasure.getLength()); // 勻速線性插值器 valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setDuration(800); valueAnimator.addUpdateListener(animation -> { float value = (Float) animation.getAnimatedValue(); pathMeasure.getPosTan(value, currentPosition, null); imageView.setX(currentPosition[0]); imageView.setY(currentPosition[1]); }); valueAnimator.start(); ObjectAnimator shoppingCartX = ObjectAnimator.ofFloat(mShoppingCart, "scaleX", 1.0f, 1.3f, 1.0f); ObjectAnimator shoppingCartY = ObjectAnimator.ofFloat(mShoppingCart, "scaleY", 1.0f, 1.3f, 1.0f); shoppingCartX.setInterpolator(new AccelerateInterpolator()); shoppingCartY.setInterpolator(new AccelerateInterpolator()); AnimatorSet shoppingCart = new AnimatorSet(); shoppingCart .play(shoppingCartX) .with(shoppingCartY); shoppingCart.setDuration(800); shoppingCart.start(); valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } //當動畫結束后: @Override public void onAnimationEnd(Animator animation) { goodsChange(data); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } });}

四、大致寫下布局(同時也算留做備份)

Android,二階貝塞爾曲線,購物車,動畫

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" ... ...> <RelativeLayout ... ...> 頂部常駐的toolbar </RelativeLayout> <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <android.support.design.widget.AppBarLayout ... ...> <android.support.design.widget.CollapsingToolbarLayout ... ... app:layout_scrollFlags="scroll|exitUntilCollapsed"> <LinearLayout  ... ...>  TabLayout上面的View   </LinearLayout> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout ... ... /> </android.support.design.widget.AppBarLayout> <RelativeLayout ... ... android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> </android.support.design.widget.CoordinatorLayout> <LinearLayout ... ...> 最下面的購物車一欄  </LinearLayout></LinearLayout>

 

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高平市| 伊川县| 安塞县| 宜良县| 许昌市| 华容县| 卢湾区| 岑巩县| 玉溪市| 台北市| 舟山市| 六盘水市| 汤原县| 无棣县| 株洲市| 类乌齐县| 曲阳县| 饶阳县| 山阳县| 临潭县| 邛崃市| 青阳县| 张北县| 德兴市| 久治县| 焦作市| 黑山县| 昭平县| 合作市| 弥渡县| 横山县| 松江区| 健康| 额济纳旗| 石狮市| 青河县| 伊川县| 道孚县| 遂昌县| 隆昌县| 西乌珠穆沁旗|