貝茲路徑實現的購物車添加商品動畫效果,貝塞爾購物車

來源:互聯網
上載者:User

貝茲路徑實現的購物車添加商品動畫效果,貝塞爾購物車

如下:

1.activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/rly_bezier_curve_shopping_cart"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin">    <FrameLayout        android:id="@+id/fly_bezier_curve_shopping_cart"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignParentLeft="true"        android:paddingRight="30dp"        android:layout_alignParentStart="true">        <ImageView            android:id="@+id/iv_bezier_curve_shopping_cart"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_gravity="right"            android:src="@drawable/menu_shop_car_selected" />        <TextView            android:id="@+id/tv_bezier_curve_shopping_cart_count"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="@color/white"            android:background="@drawable/corner_view"            android:text="0"            android:layout_gravity="right"/>    </FrameLayout>    <ListView        android:id="@+id/lv_bezier_curve_shopping_cart"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@+id/fly_bezier_curve_shopping_cart"/></RelativeLayout>

menu_shop_car_selected.png

corner_view.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="@color/red" />    <corners android:radius="10dp" />    <padding android:left="5dp" android:top="1dp"        android:right="5dp" android:bottom="1dp" /></shape>

  

2.adapter_shopping_cart_item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_marginBottom="1dp"    android:layout_height="wrap_content"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin">    <ImageView        android:id="@+id/iv_shopping_cart_item"        android:layout_width="30dp"        android:layout_height="30dp"        android:layout_centerVertical="true"        android:src="@mipmap/ic_launcher"/>    <TextView        android:id="@+id/tv_shopping_cart_item"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="購 買"        android:textSize="16sp"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"/></RelativeLayout>

3.MainActivity

public class MainActivity extends AppCompatActivity {    // 購物車父布局    private RelativeLayout mShoppingCartRly;    // 購物車列表顯示    private ListView mShoppingCartLv;    // 購物數目顯示    private TextView mShoppingCartCountTv;    // 購物車圖片顯示    private ImageView mShoppingCartIv;    // 購物車適配器    private GoodsAdapter mGoodsAdapter;    // 資料來源(購物車商品圖片)    private ArrayList<GoodsModel> mData;    // 貝茲路徑中間過程點座標    private float[] mCurrentPosition = new float[2];    // 路徑測量    private PathMeasure mPathMeasure;    // 購物車商品數目    private int goodsCount = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // findView        mShoppingCartLv = (ListView) findViewById(R.id.lv_bezier_curve_shopping_cart);        mShoppingCartCountTv = (TextView) findViewById(R.id.tv_bezier_curve_shopping_cart_count);        mShoppingCartRly = (RelativeLayout) findViewById(R.id.rly_bezier_curve_shopping_cart);        mShoppingCartIv = (ImageView) findViewById(R.id.iv_bezier_curve_shopping_cart);        // 是否顯示購物車商品數目        isShowCartGoodsCount();        // 添加資料來源        addData();        // 設定適配器        setAdapter();    }    private void setAdapter() {        // 初始化適配器        mGoodsAdapter = new GoodsAdapter(this, mData);        // 設定適配器監聽        mGoodsAdapter.setCallBackListener(new GoodsAdapter.CallBackListener() {            @Override            public void callBackImg(ImageView goodsImg) {                // 添加商品到購物車                addGoodsToCart(goodsImg);            }        });        // 設定適配器        mShoppingCartLv.setAdapter(mGoodsAdapter);    }    private void addGoodsToCart(ImageView goodsImg) {        // 創造出執行動畫的主題goodsImg(這個圖片就是執行動畫的圖片,從開始位置出發,經過一個拋物線(貝茲路徑),移動到購物車裡)        final ImageView goods = new ImageView(this);        goods.setImageDrawable(goodsImg.getDrawable());        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100);        mShoppingCartRly.addView(goods, params);        // 得到父布局的起始點座標(用於輔助計算動畫開始/結束時的點的座標)        int[] parentLocation = new int[2];        mShoppingCartRly.getLocationInWindow(parentLocation);        // 得到商品圖片的座標(用於計算動畫開始的座標)        int startLoc[] = new int[2];        goodsImg.getLocationInWindow(startLoc);        // 得到購物車圖片的座標(用於計算動畫結束後的座標)        int endLoc[] = new int[2];        mShoppingCartIv.getLocationInWindow(endLoc);        // 開始掉落的商品的起始點:商品起始點-父布局起始點+該商品圖片的一半        float startX = startLoc[0] - parentLocation[0] + goodsImg.getWidth() / 2;        float startY = startLoc[1] - parentLocation[1] + goodsImg.getHeight() / 2;        // 商品掉落後的終點座標:購物車起始點-父布局起始點+購物車圖片的1/5        float toX = endLoc[0] - parentLocation[0] + mShoppingCartIv.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(500);        // 勻速線性插值器        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會自動填滿上座標,這個方法很重要。                // mCurrentPosition此時就是中間距離點的座標值                mPathMeasure.getPosTan(value, mCurrentPosition, null);                // 移動的商品圖片(動畫圖片)的座標設定為該中間點的座標                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                goodsCount ++;                isShowCartGoodsCount();                mShoppingCartCountTv.setText(String.valueOf(goodsCount));                // 把執行動畫的商品圖片從父布局中移除                mShoppingCartRly.removeView(goods);            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });    }    private void isShowCartGoodsCount(){        if (goodsCount == 0){            mShoppingCartCountTv.setVisibility(View.GONE);        }else {            mShoppingCartCountTv.setVisibility(View.VISIBLE);        }    }    private void addData() {        // 初始化資料來源        mData = new ArrayList<>();        // 添加資料來源        GoodsModel goodsModel = new GoodsModel();        goodsModel.setmGoodsBitmap(BitmapFactory.decodeResource(getResources(),                R.drawable.goods_one));        mData.add(goodsModel);        goodsModel = new GoodsModel();        goodsModel.setmGoodsBitmap(BitmapFactory.decodeResource(getResources(),                R.drawable.goods_two));        mData.add(goodsModel);        goodsModel = new GoodsModel();        goodsModel.setmGoodsBitmap(BitmapFactory.decodeResource(getResources(),                R.drawable.goods_three));        mData.add(goodsModel);    }}

 4.GoodsAdapter

 1 public class GoodsAdapter extends BaseAdapter{ 2  3     // 資料來源(購物車商品圖片) 4     private ArrayList<GoodsModel> mData; 5     // 布局 6     private LayoutInflater mLayoutInflater; 7     // 回調監聽 8     private CallBackListener mCallBackListener; 9 10     public GoodsAdapter(Context context, ArrayList<GoodsModel> mData){11         mLayoutInflater = LayoutInflater.from(context);12         this.mData = mData;13     }14 15     @Override16     public int getCount() {17         return mData != null ? mData.size(): 0;18     }19 20     @Override21     public Object getItem(int i) {22         return mData != null ? mData.get(i): null;23     }24 25     @Override26     public long getItemId(int i) {27         return i;28     }29 30     @Override31     public View getView(int i, View view, ViewGroup viewGroup) {32         ViewHolder viewHolder;33         if (view == null){34             view = mLayoutInflater.inflate(R.layout.adapter_shopping_cart_item, null);35             viewHolder = new ViewHolder(view);36             view.setTag(viewHolder);37         }else {38             // 複用ViewHolder39             viewHolder = (ViewHolder) view.getTag();40         }41 42         // 更新UI43         if (i < mData.size())44             viewHolder.updateUI(mData.get(i));45         return view;46     }47 48     class  ViewHolder{49         // 顯示商品圖片50         private ImageView mShoppingCartItemIv;51 52         public ViewHolder(View view){53             // findView54             mShoppingCartItemIv = (ImageView) view.findViewById(R.id.iv_shopping_cart_item);55             // onClick56             view.findViewById(R.id.tv_shopping_cart_item).setOnClickListener(57                     new View.OnClickListener() {58                 @Override59                 public void onClick(View view) {60                     if (mShoppingCartItemIv != null && mCallBackListener != null)61                         mCallBackListener.callBackImg(mShoppingCartItemIv);62                 }63             });64         }65 66         public void updateUI(GoodsModel goods){67             if (goods != null68                     && goods.getmGoodsBitmap() != null69                     && mShoppingCartItemIv != null)70                 mShoppingCartItemIv.setImageBitmap(goods.getmGoodsBitmap());71         }72     }73 74     public void setCallBackListener(CallBackListener mCallBackListener){75         this.mCallBackListener = mCallBackListener;76     }77 78     public interface CallBackListener{79         void callBackImg(ImageView goodsImg);80     }81 82 }

5.GoodsModel

public class GoodsModel {    // 商品圖    private Bitmap mGoodsBitmap;    public Bitmap getmGoodsBitmap() {        return mGoodsBitmap;    }    public void setmGoodsBitmap(Bitmap mGoodsBitmap) {        this.mGoodsBitmap = mGoodsBitmap;    }}

  

  

 http://www.see-source.com/androidwidget/detail.html?wid=914

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.