购物车完整效果(下)

书接上文,我们接着说。如果你没有看 购物车完整效果(上),这篇博客的话,建议先从上篇博客看。

添加商品时的抛物线动画

文章中,第一个效果图的抛物线效果,源码中也都有的,关键代码如下:

 /**
     * 抛物线动画
     *
     * @param addView          动画开始的控件view
     * @param shoppingCartView 动画结束的控件view
     */
    private void startAnimation(View addView, View shoppingCartView) {
        int[] addLocation = new int[2];
        int[] cartLocation = new int[2];
        int[] recycleLocation = new int[2];

        addView.getLocationInWindow(addLocation);
        shoppingCartView.getLocationInWindow(cartLocation);
        mContentRecyclerView.getLocationInWindow(recycleLocation);


        PointF startP = new PointF();
        PointF endP = new PointF();
        PointF controlP = new PointF();

        //这个间距要和自定义AnimShopButton 中默认的一致
        float betweenCircle = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34, getResources().getDisplayMetrics());
        startP.x = addLocation[0] + betweenCircle;

        //startP.x = addLocation[0];
        startP.y = addLocation[1] - recycleLocation[1];

        endP.x = cartLocation[0];
        endP.y = cartLocation[1] - recycleLocation[1];


        controlP.x = endP.x;
        controlP.y = startP.y;


        final FakeAddImageView fakeAddImageView = new FakeAddImageView(this);
        mainLayout.addView(fakeAddImageView);
        fakeAddImageView.setImageResource(R.drawable.ic_bug_cart);
        fakeAddImageView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.height_20);
        fakeAddImageView.getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.height_20);

        fakeAddImageView.setVisibility(View.VISIBLE);
        ObjectAnimator addAnimator = ObjectAnimator.ofObject(fakeAddImageView, "mPointF",
                new PointFTypeEvaluator(controlP), startP, endP);
        addAnimator.setInterpolator(new AccelerateInterpolator());
        addAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
                fakeAddImageView.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                fakeAddImageView.setVisibility(View.GONE);
                mainLayout.removeView(fakeAddImageView);

                totalPriceCalculation();//当动画结束之后,在更新数量

            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });

        ObjectAnimator scaleAnimatorX = new ObjectAnimator().ofFloat(shoppingCartView, "scaleX", 0.6f, 1.0f);
        ObjectAnimator scaleAnimatorY = new ObjectAnimator().ofFloat(shoppingCartView, "scaleY", 0.6f, 1.0f);
        scaleAnimatorX.setInterpolator(new AccelerateInterpolator());
        scaleAnimatorY.setInterpolator(new AccelerateInterpolator());
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(scaleAnimatorX).with(scaleAnimatorY).after(addAnimator);
        animatorSet.setDuration(800);
        animatorSet.start();
    }

底部弹出购物车清单

这里用的是 bottomsheet 这个开源库。用法不再废话了,关键代码:

 /*底部弹框 购物车 相关 stat */

    private void showPopupWindow(List<ShopCartBean> shopCartBeans) {
        //if (bottomSheet == null) {
        View bottomSheet = createBottomSheetView(shopCartBeans);//底层视图初始化
        // }
        if (bottomSheetLayout.isSheetShowing()) {
            bottomSheetLayout.dismissSheet();
        } else {
            bottomSheetLayout.showWithSheetView(bottomSheet);
        }

    }

底部购物车清单列表和右边商品列表的联动 (重点)

这篇博客,我们重点,说这里!说到这里,我们得先说明一下,购物车中商品的保存问题。说到保存,其实方案无非是两种:

1:加入购物车的商品保存在后台
保存在后台,每次的商品添加和减少,我们都要调取接口,这样对于app端来说,确实省了不少事,处理起来也方便不少。不太好的地方,就是调接口太频繁。如果后台开发人员比较牛,这种问题应该都是小问题。项目源码 中还没有对这种情况做展示处理。不过思路都差不多。

2: 加入购物车的商品保存在app本地
保存在app本地,也是一种不错的方案。项目源码 中,用的数据库框架是 GreenDao3.2,性能比较高。当然郭神的LitePal也很好啦!现在都更新到了3.0!

首先是商品的添加和减少,我们都要实时做本地数据库的更新处理。关键代码:

 mContentAdapter.setOnAnimShopClickListener(new ContentAdapter.OnAnimShopClickListener() {
            @Override
            public void onAddSuccess(View view, int count, int position) {

                ContentResult itemData = mContentAdapter.getItem(position);

                saveData(count, itemData);

                updateContentAdapter(itemData.getCount(), itemData.getProduct_id());

                startAnimation(view, imageCart);

            }

            @Override
            public void onDelSuccess(View view, int count, int position) {

                ContentResult itemData = mContentAdapter.getItem(position);

                saveData(count, itemData);

                updateContentAdapter(itemData.getCount(), itemData.getProduct_id());

                totalPriceCalculation();
            }
        });

每次点击底部购物车时,我们要根据当前用户,查出已经加入购物车的商品,关键代码如下:

 frameShopCart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (tvNumber.getVisibility() == View.VISIBLE) {
                    List<ShopCartBean> shopCartBeans = shopCartBeanDao.queryBuilder()
                            .where(ShopCartBeanDao.Properties.User_id
                                    .eq(mPreferencesUtil.getUserId()))
                            .build().list();

                    showPopupWindow(shopCartBeans);
                }

            }
        });

下面关键问题来了,我们如何做到 底部购物车清单列表和右边商品列表的联动呢?
首先,当物车清单列表中的商品做增加或减少处理时,我们先要更新本地数据数据;
然后, 去 遍历 右边 列表,发现相同商品id的商品,它们的个数都要更新,然后刷新列表即可。
关键代码:

/**
     * 刷新内容adapter
     */
    private void updateContentAdapter(int count, String productId) {
        // TODO: 2019/1/12 0012 这里后续优化,可以这样优化,相同商品的个数超过2个的再去刷新列表,否则就不要刷新列表啦

        //去遍历列表,发现商品id相同的,个数 都赋值一样的。
        for (ContentResult result : mContentResultList) {
            if (productId.equals(result.getProduct_id())) {
                result.setCount(count);
            }
        }
        if (count == 0) {
            //这样能保证动画效果能执行完毕,否则动画效果就会没有了。当然也可不做这样的处理,直接去刷新列表即可。
            new Handler().postDelayed(() -> mContentAdapter.notifyDataSetChanged(), 400);
        } else {
            mContentAdapter.notifyDataSetChanged();
        }
    }

一些细节处理和注意事项

(1)商品加入购物车时,本地保存时要区分是哪个用户的。

(2)购物车商品减少时,减到0时的处理。

(3)一般商品类别中第一项会是 打折促销 等类别,这个类别的商品id会和其他类别的商品id相同。要考虑到这种情况下的处理。

最后,文章从整理到写好,也花费了不少时间,如果对你有些帮助的话,给点个赞吧,谢谢啦!

源码git地址

发布了82 篇原创文章 · 获赞 131 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/da_caoyuan/article/details/86496355