Android仿饿了么购物车功能

625 阅读3分钟

现在商城应用上,购物车功能可以说是不可缺少的,每个应用的购物车模块实现方式都差不多,这篇我们来仿一下饿了么的购物车功能,用过的童鞋都知道,印象最深刻的应该是添加或减少数量时,抛物线的动画效果,话不多说,现在让我们来看看是怎么实现的吧.

先看效果图

在这里插入图片描述

效果图可以看出,这个布局还是比较简单的,重点应该还是在抛物线的动画上.

1、列表布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

    <RelativeLayout
        android:id="@+id/rl_main"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="#ffffff"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/tv_titlebar_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dp"
            android:padding="5dp"
            android:src="@drawable/danghanglan_fanhui" />

        <TextView
            android:id="@+id/tv_titlebar_center"
            android:layout_width="200dp"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:ellipsize="end"
            android:gravity="center"
            android:maxLength="18"
            android:singleLine="true"
            android:text="购物车"
            android:textColor="#2f302b"
            android:textSize="17sp"
            android:visibility="visible" />

        <TextView
            android:id="@+id/tv_titlebar_right"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:background="@null"
            android:gravity="center"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:singleLine="true"
            android:text="编辑"
            android:textColor="#2f302b"
            android:textSize="14sp"
            android:visibility="gone" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_alignParentBottom="true"
            android:background="#cccccc" />
    </RelativeLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/rl_main"
        android:layout_marginBottom="40dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#fff"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp">

            <ImageView
                android:id="@+id/iv_shop_cart"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:padding="2dp"
                android:src="@mipmap/img_revision_shopping_car" />

            <TextView
                android:id="@+id/tv_num"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_gravity="right"
                android:background="@drawable/tip_message_revision_bg"
                android:gravity="center"
                android:text="11"
                android:textColor="#fff"
                android:visibility="gone" />
        </FrameLayout>

        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" />

        <TextView
            android:layout_width="80dp"
            android:layout_height="30dp"
            android:layout_marginRight="10dp"
            android:background="#d4ab7f"
            android:gravity="center"
            android:text="购买"
            android:textColor="#ffffff" />
    </LinearLayout>
</RelativeLayout>

2、模拟初始化数据

 //添加商品数据
        final List<CartModel> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            CartModel cartModel = new CartModel();
            cartModel.setName("麻辣肉碎面-----" + i);
            list.add(cartModel);
        }

3、设置数据

 final ShoppingAdapter shoppingAdapter = new ShoppingAdapter(this, list);
 mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
 mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
 mRecyclerView.setAdapter(shoppingAdapter);

4、点击加号操作这里分二钟情况:

一是当数量为0时减号会执行旋转和平移渐变的动画, 二是数量不为0时只会进行抛物线动画,其中抛物线动画实现思路就是得到加号和购物车的坐标,然后得到最外层容器添加一个view来执行这个动画,动画执行完成后移除这个动画:

  //点击加号
 myHolder.imageViewAdd.setOnClickListener(new View.OnClickListener() {
      @Override
       public void onClick(View v)
            final CartModel cartModel = mDatas.get(position);
             //如果该商品数量为0就进行这个动画
             if (cartModel.getCount() == 0) {
                    myHolder.imageViewReduce.setVisibility(View.VISIBLE);
                    myHolder.tvAmount.setVisibility(View.VISIBLE);
                    AnimatorSet set = new AnimatorSet();
                    //减号
                    ObjectAnimator ta1 = ObjectAnimator.ofFloat(myHolder.imageViewReduce, "translationX", mAddLeft - mReduceLeft, 0);
                    ObjectAnimator ra1 = ObjectAnimator.ofFloat(myHolder.imageViewReduce, "rotation", 0, 360);
                    ObjectAnimator aa1 = ObjectAnimator.ofFloat(myHolder.imageViewReduce, "alpha", 0, 1);

                    //数字
                    ObjectAnimator ta2 = ObjectAnimator.ofFloat(myHolder.tvAmount, "translationX", mAddLeft - mAmountLeft, 0);
                    ObjectAnimator ra2 = ObjectAnimator.ofFloat(myHolder.tvAmount, "rotation", 0, 360);
                    ObjectAnimator aa2 = ObjectAnimator.ofFloat(myHolder.tvAmount, "alpha", 0, 1);
                    set.play(ta1).with(ra1).with(ta2).with(ra2).with(aa1).with(aa2);
                    set.setDuration(500).start();
                }
                //addGoods2CartAnim((ImageView) v,cartModel);
                //得到加号在屏幕的坐标
                int[] addLocation = new int[2];
                v.getLocationInWindow(addLocation);
                //得到购物车图标的坐标
                int[] cartLocation = mActivity.getCartLocation();
                //添加一个imageview
                final ImageView iv = new ImageView(v.getContext());
                iv.setBackgroundResource(R.drawable.icon_shop_add);
                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(v.getWidth(), v.getHeight());
                lp.leftMargin = addLocation[0];
                lp.topMargin = addLocation[1] - v.getHeight();

                mActivity.getContainer().addView(iv, lp);
                //横向移动
                ObjectAnimator oaX = ObjectAnimator.ofFloat(iv, "translationX", cartLocation[0] - addLocation[0] + v.getWidth() / 2);
                //纵向
                ObjectAnimator oaY = ObjectAnimator.ofFloat(iv, "translationY", cartLocation[1] - addLocation[1]);
                oaX.setInterpolator(new LinearInterpolator());
                oaY.setInterpolator(new AccelerateInterpolator());
                AnimatorSet set = new AnimatorSet();
                set.play(oaX).with(oaY);
                set.setDuration(500).start();
                set.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {}

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        //移除这个view
                        mActivity.getContainer().removeView(iv);
                        //跟新购物车
                        cartModel.setCount(cartModel.getCount() + 1);
                        ((MyHolder) holder).tvAmount.setText(String.valueOf(cartModel.getCount()));
                        mActivity.mCount++;
                        mActivity.setMtvNum();
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {}

                    @Override
                    public void onAnimationRepeat(Animator animation) {}
                });
            }
        });

5、减法动画效果

  //点击减号
        myHolder.imageViewReduce.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final CartModel cartModel = mDatas.get(position);
                //如果该商品数量为1就进行这个动画
                if (cartModel.getCount() == 1) {
                    AnimatorSet set = new AnimatorSet();
                    //减号
                    ObjectAnimator ta1 = ObjectAnimator.ofFloat(myHolder.imageViewReduce, "translationX", 0, mAddLeft - mReduceLeft);
                    ObjectAnimator ra1 = ObjectAnimator.ofFloat(myHolder.imageViewReduce, "rotation", 0, 360);
                    ObjectAnimator aa1 = ObjectAnimator.ofFloat(myHolder.imageViewReduce, "alpha", 1, 0);

                    //数字
                    ObjectAnimator ta2 = ObjectAnimator.ofFloat(myHolder.tvAmount, "translationX", 0, mAddLeft - mAmountLeft);
                    ObjectAnimator ra2 = ObjectAnimator.ofFloat(myHolder.tvAmount, "rotation", 0, 360);
                    ObjectAnimator aa2 = ObjectAnimator.ofFloat(myHolder.tvAmount, "alpha", 1, 0);
                    set.play(ta1).with(ra1).with(ta2).with(ra2).with(aa1).with(aa2);
                    set.setDuration(500).start();
                    set.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {}

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            cartModel.setCount(cartModel.getCount() - 1);
                            myHolder.tvAmount.setText(String.valueOf(cartModel.getCount()));
                            if(cartModel.getCount()==0){
                                myHolder.tvAmount.setVisibility(View.INVISIBLE);
                                myHolder.imageViewReduce.setVisibility(View.INVISIBLE);
                            }
                            mActivity.mCount--;
                            mActivity.setMtvNum();
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {}

                        @Override
                        public void onAnimationRepeat(Animator animation) {}
                    });

                } else {
                    cartModel.setCount(cartModel.getCount() - 1);
                    myHolder.tvAmount.setText(String.valueOf(cartModel.getCount()));
                    mActivity.mCount--;
                    mActivity.setMtvNum();
                }

            }
        });

该功能的实现重点在抛物线的动画效果上,这里就不把完整的代码添加进去了,不然影响阅读体验,需要完整源码的童鞋底部关注公众号回复:"仿饿了么购物车" 即可获得哦.

到这里就结束啦.


以下是公众号(longxuanzhigu),之后发布的文章会同步到该公众号,方便交流学习Android知识,欢迎关注:

在这里插入图片描述