您好,登錄后才能下訂單哦!
一、引入
二、大致思路
1、如圖所示主要有三個(gè)點(diǎn),起點(diǎn)、終點(diǎn)、以及貝塞爾曲線的控制點(diǎn)
2、起點(diǎn)即點(diǎn)擊的View的位置,一般來說用如下方式即可取得。startPosition[0]為x軸開始坐標(biāo),startPosition[1]為Y軸終點(diǎn)坐標(biāo),兩點(diǎn)可以看作對(duì)角線上面的兩個(gè)端點(diǎn)(左上角x坐標(biāo),右下角y坐標(biāo))
//貝塞爾起始數(shù)據(jù)點(diǎn) int[] startPosition = new int[2]; view.getLocationOnScreen(startPosition);
3、終點(diǎn)即購物車籃子的位置,與起點(diǎn)類似
mShoppingCart.getLocationInWindow(endPosition);
4、控制點(diǎn),我選的控制點(diǎn)為上圖的C點(diǎn),即A點(diǎn)的y坐標(biāo),B點(diǎn)的X坐標(biāo)
controlPosition[0] = endPosition[0]; controlPosition[1] = startPosition[1];
5、需要注意的地方,我不清楚是不是因?yàn)槲业牟季值膯栴},獲取到的點(diǎn)擊的A點(diǎn)總是會(huì)有一個(gè)偏移,后來經(jīng)同事提醒,減去了TabLayout的坐標(biāo)的y軸坐標(biāo)即位置才可以。
// 起點(diǎn) int[] startPosition; // 終點(diǎn) int[] endPosition = new int[2]; // 貝塞爾控制點(diǎn) int[] controlPosition = new int[2]; // tablayout位置 int[] tablayoutPosition = new int[2]; startPosition = data.getStartPosition(); mShoppingCart.getLocationInWindow(endPosition); mTabLayout.getLocationInWindow(tablayoutPosition); // 處理起點(diǎn)y坐標(biāo)偏移的問題 startPosition[1] = startPosition[1] - tablayoutPosition[1] - mTabLayout.getHeight(); // 終點(diǎn)進(jìn)行一下居中處理 endPosition[0] = endPosition[0] + (mShoppingCart.getWidth() / 2); controlPosition[0] = endPosition[0]; controlPosition[1] = startPosition[1];
6、通過Path的quadTo方法繪制貝塞爾曲線,使用PathMeasure獲取點(diǎn)的坐標(biāo)(借助ValueAnimator.ofFloat()配合getPosTan()來獲取坐標(biāo))
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是一個(gè)生成器 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、下面是用屬性動(dòng)畫給購物車籃子做了一個(gè)放大縮小的動(dòng)畫效果
// mShoppingCart是View 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();
三、稍完整的大部分代碼
private void AddAnimation(AddEventBean data) { // 起點(diǎn) int[] startPosition; // 終點(diǎn) int[] endPosition = new int[2]; // 貝塞爾控制點(diǎn) int[] controlPosition = new int[2]; // 當(dāng)前位置 float[] currentPosition = new float[2]; // tablayout位置 int[] tablayoutPosition = new int[2]; startPosition = data.getStartPosition(); mShoppingCart.getLocationInWindow(endPosition); mTabLayout.getLocationInWindow(tablayoutPosition); // 處理起點(diǎn)y坐標(biāo)偏移的問題 startPosition[1] = startPosition[1] - tablayoutPosition[1] - mTabLayout.getHeight(); // 終點(diǎn)進(jìn)行一下居中處理 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是一個(gè)生成器 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) { } //當(dāng)動(dòng)畫結(jié)束后: @Override public void onAnimationEnd(Animator animation) { goodsChange(data); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); }
四、大致寫下布局(同時(shí)也算留做備份)
<?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>
五、推薦資源
View的位置參數(shù)
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。