先看下效果图:

ezgif-1-8f133ca916.gif

1.首先列表布局采用Recycleview

android:id="@+id/container"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/rv"

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:background="#fff"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_marginLeft="10dp"

android:layout_marginRight="10dp"

android:gravity="center_vertical"

android:orientation="horizontal">

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android:id="@+id/iv_shop_cart"

android:layout_width="40dp"

android:layout_height="40dp"

android:padding="2dp"

android:src="@mipmap/icon_shop_shopcart"/>

android:visibility="gone"

android:gravity="center"

android:text="11"

android:id="@+id/tv_num"

android:textColor="#fff"

android:layout_gravity="right"

android:background="@drawable/cart_num"

android:layout_width="20dp"

android:layout_height="20dp"/>

android:layout_width="0dp"

android:layout_height="1dp"

android:layout_weight="1"/>

android:layout_width="80dp"

android:layout_height="30dp"

android:layout_marginRight="6dp"

android:background="#f17334"

android:gravity="center"

android:text="购买"

android:textColor="#ffffff"/>

2.购物车item布局

android:layout_width="match_parent"

android:layout_height="120dp"

android:background="#fff"

android:orientation="horizontal">

android:id="@+id/iv"

android:layout_width="120dp"

android:layout_height="120dp"

android:src="@mipmap/icon_shop_goods"/>

android:id="@+id/tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="10dp"

android:layout_marginTop="10dp"

android:layout_toRightOf="@+id/iv"

android:text="麻辣牛肉粉"

android:textColor="#000"/>

android:id="@+id/tv2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/tv"

android:layout_marginLeft="10dp"

android:layout_marginTop="10dp"

android:layout_toRightOf="@+id/iv"

android:text="精选上等黄牛肉,加上特制秘方..."

android:textSize="12sp"/>

android:id="@+id/tv3"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/tv2"

android:layout_marginLeft="10dp"

android:layout_marginTop="10dp"

android:layout_toRightOf="@+id/iv"

android:background="@drawable/shape_discount"

android:paddingLeft="4dp"

android:paddingRight="2dp"

android:text="8折"

android:textColor="#fff"

android:textSize="12sp"/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/tv2"

android:layout_marginTop="10dp"

android:layout_toRightOf="@+id/tv3"

android:background="@drawable/shape_users"

android:paddingLeft="4dp"

android:paddingRight="4dp"

android:text="饿了么vip专享"

android:textColor="#fff"

android:textSize="12sp"/>

android:id="@+id/tv_price"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_marginLeft="10dp"

android:layout_marginTop="40dp"

android:layout_toRightOf="@+id/iv"

android:text="¥19.99元"

android:textColor="#ff00"/>

android:id="@+id/tv_old"

android:layout_alignParentBottom="true"

android:layout_toRightOf="@id/tv_price"

android:layout_marginLeft="5dp"

android:text="¥28.50元"

android:textSize="13sp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

android:id="@+id/iv_reduce"

android:layout_width="25dp"

android:layout_height="25dp"

android:layout_alignBottom="@+id/tv_price"

android:layout_toLeftOf="@+id/tvamount"

android:src="@mipmap/icon_shop_reduce"/>

android:id="@+id/tvamount"

android:layout_width="25dp"

android:layout_height="25dp"

android:layout_alignBottom="@+id/tv_price"

android:layout_centerInParent="true"

android:layout_toLeftOf="@+id/iv_add"

android:gravity="center"

android:text="1"

android:textColor="#000"/>

android:id="@+id/iv_add"

android:layout_width="25dp"

android:layout_height="25dp"

android:layout_alignBottom="@+id/tv_price"

android:layout_alignParentRight="true"

android:layout_marginRight="10dp"

android:src="@mipmap/icon_shop_add"/>

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

//得到加号在屏幕的坐标

int[] addLocation = new int[2];

v.getLocationInWindow(addLocation);

//得到购物车图标的坐标

int[] cartLocation = mActivity.getCartLocation();

//添加一个imageview

final ImageView iv = new ImageView(v.getContext());

iv.setBackgroundResource(R.mipmap.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();

4.完整代码:

private RecyclerView mRecyclerView;

private ImageView mIvCart;

private RelativeLayout mContainer;

private TextView mtvNum;

public int mCount = 0;

@Override

public void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_shopping_cart);

mRecyclerView = findViewById(R.id.rv);

mIvCart = findViewById(R.id.iv_shop_cart);

mContainer = findViewById(R.id.container);

mtvNum = findViewById(R.id.tv_num);

final List list = new ArrayList<>();

for (int i = 0; i < 20; i++) {

CartModel cartModel = new CartModel();

cartModel.setName("红烧牛肉面" + i);

list.add(cartModel);

}

final ShoppingAdapter shoppingAdapter = new ShoppingAdapter(this, list);

mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));

mRecyclerView.setAdapter(shoppingAdapter);

//购物车点击事件的回调

}

/**

* 得到布局最外层

*

* @return

*/

public RelativeLayout getContainer() {

return this.mContainer;

}

/**

* 得到购物车在窗体上的坐标

*

* @return

*/

public int[] getCartLocation() {

int[] cartLocation = new int[2];

mIvCart.getLocationInWindow(cartLocation);

return cartLocation;

}

public void setMtvNum() {

if (mCount > 0) {

mtvNum.setText(String.valueOf(mCount));

mtvNum.setVisibility(View.VISIBLE);

}else {

mtvNum.setVisibility(View.GONE);

}

}

private List mDatas;

private int mAmountLeft;

private int mReduceLeft;

private int mAddLeft;

private ShoppingCartActivity mActivity;

public ShoppingAdapter(Activity activity, List list) {

mDatas = list;

this.mActivity = (ShoppingCartActivity) activity;

}

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_shopping_cart, parent, false);

MyHolder holder = new MyHolder(view);

return holder;

}

@Override

public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

final MyHolder myHolder = (MyHolder) holder;

myHolder.setItem(position);

//点击加号

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.mipmap.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) {}

});

}

});

//点击减号

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();

}

}

});

}

@Override

public int getItemCount() {

return mDatas.size();

}

class MyHolder extends RecyclerView.ViewHolder {

TextView title;

ImageView imageViewAdd;

ImageView imageViewReduce;

TextView tvAmount;

TextView tvOld;

public MyHolder(View itemView) {

super(itemView);

title = itemView.findViewById(R.id.tv);

imageViewAdd = itemView.findViewById(R.id.iv_add);

imageViewReduce = itemView.findViewById(R.id.iv_reduce);

tvAmount = itemView.findViewById(R.id.tvamount);

tvOld = itemView.findViewById(R.id.tv_old);

tvOld.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);

imageViewAdd.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//得到加号的左边位置

mAddLeft = imageViewAdd.getLeft();

imageViewAdd.getViewTreeObserver().removeOnGlobalLayoutListener(this);

}

});

imageViewReduce.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//得到减号的左边位置

mReduceLeft = imageViewReduce.getLeft();

imageViewReduce.getViewTreeObserver().removeOnGlobalLayoutListener(this);

}

});

tvAmount.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//得到价格的左边位置

mAmountLeft = tvAmount.getLeft();

tvAmount.getViewTreeObserver().removeOnGlobalLayoutListener(this);

}

});

}

public void setItem(int position) {

CartModel cartModel = mDatas.get(position);

title.setText(cartModel.getName());

tvAmount.setText(String.valueOf(cartModel.getCount()));

if (cartModel.getCount() > 0) {//数目大于0就显示

imageViewReduce.setVisibility(View.VISIBLE);

tvAmount.setVisibility(View.VISIBLE);

} else {//数目小于0就隐藏

imageViewReduce.setVisibility(View.INVISIBLE);

tvAmount.setVisibility(View.INVISIBLE);

}

}

}

android 购物车 简书,Android仿饿了么购物车效果相关推荐

  1. android matrix 简书,[Android] ImageView ScaleType完全解析

    ImageView有一个ScaleType的属性,该属性决定了图片在ImageView上的展现形式,包括:是否进行缩放.如何进行缩放.缩放之后图片的摆放位置等等.官方介绍如下: Options for ...

  2. android spinner 简书,Android NiceSpinner

    NiceSpinner 是 Android 端的一款第三方控件,自带箭头动画效果 真的是简单又好用哦!有需要的小伙伴们可以试试啦. 效果图如下: image 1. 导入模块 在 Github 下载并导 ...

  3. Android入门简书,android ndk开发入门随笔(一)

    ndk,jni入门随笔 因为工作缘故最近在研究jni,ndk方面知识,在此总结入坑以来的一些问题. 配置环境可以在下面geogle官方看.下面是链接 我一说ndk,jni可能小伙伴要问了这是什么,在此 ...

  4. android opengl 简书,Android OpenGL入门

    如今VR这么火,感觉有必要先把OpenGL学好,为以后转VR奠定一些基础.一年前,接触过Android的OpenGL,当时是实现了在Android上显示标准的3D文件(STL格式).现在打算整理一下O ...

  5. android room 简书,Android Room 的坑

    在添加依赖时,官网给出的是: def room_version = "2.0.0-beta01" implementation "androidx.room:room-r ...

  6. android 音乐 简书,Android音频开发(7):音乐可视化-FFT频谱图

    Android 音频开发 目录 一.演示 image 二.实现 实现流程: 使用MediaPlayer播放传入的音乐,并拿到mediaPlayerId 使用Visualizer类拿到拿到MediaPl ...

  7. android 心跳 简书,Android Socket保持心跳长连接,断线重连

    昨天三点钟才睡觉的,现在胸口感觉闷闷的,兄弟们,我是不是要GG了?如果我G了,求大佬们给我烧个女朋友, ss.gif 1.在使用Socket连接客户端和服务器端的时候,如果服务端断开了连接,我们客户端 ...

  8. android zxing简书,Android集成zxing 版本3.4.1

    第一步:去官网下载最新jar 或者 'implementation 'com.google.zxing:core:3.4.1''引入项目. 如下图: yhx.png 如何查看最新版本: yhx.png ...

  9. android realm 简书,android 数据库SQLite realm

    一.SQLite android内置了数据库SQLite,这是一款轻量级的关系型数据库,通常只需要几百K的内存.数据库文件存放在/data/data//databases/目录下. 为了方便管理数据库 ...

最新文章

  1. 学术期刊因投稿者并非双一流高校作者而拒稿引热议!这算学历歧视吗?
  2. frida hook java层常用模板
  3. 支付宝个人账单出来了,这里有最全的查看攻略!
  4. mysql存储引擎innodb_MySQL常用存储引擎之Innodb
  5. java课程课后作业190502之单词统计续集
  6. 大数据分析实战-信用卡欺诈检测(三)- 模型评估
  7. 剑指offer三从头到尾打印链表
  8. go语言 gosched
  9. java+io体系结构图_Java IO 体系结构
  10. office插件开发_理工科公式编辑工具——Aurora插件
  11. Filter过滤器详解
  12. Linux 压测工具 stress 安装下载
  13. 互联网公司裁员潮传言四起,是捕风捉影还是确有其事?
  14. css怎么修改图片像素,怎么改变图片宽度_word怎么改变图片像素大小
  15. 云览天下,一触即达——QQ 浏览器(android) 设计之路
  16. 数据结构与算法邓俊辉——(二)
  17. html背景斜线,巧妙的实现 CSS 斜线(炫酷的小效果)
  18. 关于T—SQL与SQL企业管理器
  19. 基于MCR的MATLAB使用案例
  20. 微信小程序直播功能来了,然后呢?

热门文章

  1. 小程序轮播图swiper点击图片自定义跳转
  2. 微信公众号排版多少钱一篇?
  3. Android实践--模拟器的加度的快感
  4. 思科模拟器 --- 交换机的Telnet 远程
  5. 快速免费建站程序推荐,个人站长快速建站程序必知
  6. go html桌面,Go语言:开发GUI桌面应用(andlabs/ui)
  7. 侃侃企业网管那些烦心事
  8. 自定义Toast实现多次触发只显示一次toast使用改良
  9. 网络系统集成工程师——十八般武艺
  10. 在线协作软件的三个核心引擎