这是一个点击购买按钮弹出一个图片落到购物车的一个案例,效果图片如下

android 购物街面 android实现购物的小案例_控件

这个案例除了对动画的使用以外,右下角还用到了一个比较好用的自定义View
BadgeView 相当于为一个控件添加一个类似于附加解释的红框,在QQ微信上面经常会看到它,这里呢有个对这个View使用的解释链接


在本案例中对 BadgeView 使用的代码

badgeView = new BadgeView(this);
        badgeView.setTargetView(shopcar_iv);
        badgeView.setBackgroundColor(Color.RED);
        badgeView.setTextColor(Color.WHITE);
        badgeView.setTextSize(12);

关于这个购物车动画
我的思路如下
1.创建一个动画层,仅仅用来放置小球的View
3.定义小球的动画
4.创建小球的View,将小球的View添加到动画层,并为小球添加动画

让我们一层层分析都做写什么

创建动画层

为了对小球的View操作更加清楚,我们要将小球的View单独放到一个动画层当中,就是在手机屏幕的基础上再创建一个透明的Layout布局,而不是将小球View放在整个Activity中

1.要得到当前手机屏幕最底层,将在最底层上面创建这个动画层
2.有了这个layout布局之后,为这个布局设置属性,比如宽高,透明度什么的
3.将这个动画层添加到第一步获得的底层布局的上面

//创建小球所在的动画层
    private ViewGroup createAniLayout() {
        //得到当前手机屏幕窗口最底层的View
        ViewGroup rootView = (ViewGroup) ShopCarActivity.this.getWindow().getDecorView();
        //构造动画层
        LinearLayout aniLayout = new LinearLayout(ShopCarActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);//设置动画层大小
        aniLayout.setLayoutParams(lp);
        aniLayout.setBackgroundResource(android.R.color.transparent);//将布局设置成透明

        //将动画层添加进去
        rootView.addView(aniLayout);
        return aniLayout;
    }

定义小球动画

由效果图可以看出小球做的是一个抛物线运动
抛物线运动:水平匀速运动,竖直方向匀加速运动
动画方面的是补间动画,因为补间动画的一些缺陷,可能即使是加上了缩放和旋转的功能也是无法实现预期效果的,所以只添加了一个平移的效果

因为动画结束后小球会再回到起始位置,所以要对小球添加一个监听,在动画结束后,隐藏小球,那么动画开始时就要显示小球,同样还有一个小球落下购物车右上角购买数量改变的效果

1.得到左下角购物车的View的图标的位置
2.计算小球走的路径,分为水平和垂直
3.定义平移动画,起始位置都是不变的0,结束位置就是所走的位移
4.为小球设置动画

private void initAni(int start_loc[], final View v) {
        //构造动画
        //得到购物车图片的终点坐标
        int end_loc[] = new int[2];
        shopcar_iv.getLocationInWindow(end_loc);
        //实现动画
        //计算位移
        int x = end_loc[0] - start_loc[0];
        int y = end_loc[1] - start_loc[1];
        TranslateAnimation translateAnimationX = new TranslateAnimation(0, x, 0, 0);
        translateAnimationX.setInterpolator(new LinearInterpolator());
        //动画结束时停留在最后一帧,不然会回到没有执行前的状态
        translateAnimationX.setFillAfter(true);
        TranslateAnimation translateAnimationY = new TranslateAnimation(0, 0, 0, y);
        translateAnimationY.setInterpolator(new LinearInterpolator());
        translateAnimationY.setFillAfter(true);
        AnimationSet set = new AnimationSet(false);
        set.addAnimation(translateAnimationX);
        set.addAnimation(translateAnimationY);
        set.setDuration(800);
        v.startAnimation(set);
        set.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                v.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                v.setVisibility(View.GONE);
                //设置购物车图标右上角的数字加一
                buyNum++;
                badgeView.setBadgeCount(buyNum);
                badgeView.setGravity(Gravity.TOP | Gravity.RIGHT);

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });


    }

创建小球View,将其添加到动画层并设置上动画

1.创建一个小球的View,用ImageView即可,为这个View设置宽高和背景图片
2.将这个View添加到动画层
3.调用上面写的创建动画的方法,为View设置上动画

/**
     * 创建小球的View,添加小球的View到动画层,并显示动画
     *
     * @param start_loc  start_loc[0] 小球开始运动的x轴坐标,start_loc[1]小球开始运动的y坐标
     * @param viewGroups 将小球的View添加到那个动画层
     */

    private void createBallView(int[] start_loc, ViewGroup viewGroups) {
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT
                , ViewGroup.LayoutParams.WRAP_CONTENT);//设置小球的大小
        //设置小球的起始位置
        lp.leftMargin = start_loc[0];
        lp.topMargin = start_loc[1];
        ImageView imageView = new ImageView(ShopCarActivity.this);
        imageView.setLayoutParams(lp);
        imageView.setImageResource(R.drawable.cry);
        viewGroups.addView(imageView);
        //上面写的为小球添加动画的方法
        initAni(start_loc, imageView);
    }

最后

在ListView的Adapter中,把每一个条目的btn的点击事件中调用这个总方法就好了

btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //小球是从Button发出的,所以要获取Button的x和y的坐标
                    int start_loc[] = new int[2];
                    //得到当前点击控件所在屏幕中的坐标
                    v.getLocationInWindow(start_loc);
                    //创建小球并实现小球的动画
                    createBallView(start_loc, createAniLayout());
                }
            });