年底忙碌起来便挤不出时间更新笔记文章了,趁今天周末抽空把之前的功能笔记补齐O(∩_∩)O哈哈~
记录到这个功能我首先要感谢一下我目前的老大对我的帮助,一位英俊潇洒风流倜傥阳光幽默精通各大代码域的帅小伙guthub:https://github.com/KnifeStone
一.概述 :
EventBus是针对Android优化的发布/订阅事件总线。主要是替代Intent/Handler/BroadCast在Fragment/Activity/Service线程之间传递消息。开销小,代码更优雅,将发送者和接收者解耦。
二.推荐:
针EventBus的简单用法推荐(作者写得通俗易懂)
http://blog.csdn.net/harvic880925/article/details/40660137
更深入了解EventBus推荐
http://www.jianshu.com/p/31e3528ca7e5
(1). EventBus官网地址
(2). EventBus github地址
(3). EventBus 3.0的用法详解
三.实现步骤:
按照以往的惯例先上效果图:
看完效果图可以知道实现添加购物车分为几部分:
首先先简单写一个产品列表,数据是存储在七牛云上面的临时数据,先拿来用。
github下载地址,欢迎star:https://github.com/LXLYHM/EventBusAddShoppingCart/blob/master/README.md
代码注释比较详细,感兴趣的小伙伴可以下载看看,下面直接上干货,就不多解释废话了
1.网络框架:是自封装的一个非常简单的Retrofit2网络框架
2.重点主要在加入购物车的时候使用EventBus全局通知事件上
首先是在总工程的build.gradle接入开源库资源:
allprojects {
repositories {
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
然后在app的build.gradle引用开源库:
compile 'org.greenrobot:eventbus:3.0.0'
在基类AddCartActivity.java里面注册关闭好EventBus和实现加入购物车动画给MainActivity.java继承:
public abstract class AddCartActivity extends AppCompatActivity {
protected QBadgeView qBadgeView = null;//购物车数量红点
protected ObjectAnimator animator = null;//动画view
@Override
protected void onStart() {
super.onStart();
//onStart的时候注册EventBus
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
}
@Override
protected void onStop() {
super.onStop();
//onStop的时候释放EventBus
EventBus.getDefault().unregister(this);
}
//发送消息线程
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(ProductAnimEvent event) {
if (qBadgeView == null) {
return;
}
View view = event.view;
//获取商品坐标
int[] goodsPoint = new int[2];
view.getLocationInWindow(goodsPoint);
//获取购物车坐标
int[] shoppingCartPoint = new int[2];
qBadgeView.getLocationInWindow(shoppingCartPoint);
//生成商品View 并播放商品加入购物车动画
ProductAnimView animView = new ProductAnimView(this);
ImageLoader.getInstance().loadRound(event.imgPath, animView);
animView.setCircleStartPoint(goodsPoint[0] + view.getWidth() / 2 - ConvertUtils.dp2px(24f), goodsPoint[1] + view.getHeight() / 2 - ConvertUtils.dp2px(24f));
animView.setCircleEndPoint(shoppingCartPoint[0], shoppingCartPoint[1] - ConvertUtils.dp2px(24f));
ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
decorView.addView(animView, ConvertUtils.dp2px(48f), ConvertUtils.dp2px(48f));
animView.startAnimation();
//判断是否播放小红点跳跃动画
if (animator == null && qBadgeView != null) {
animator = ObjectAnimator.ofFloat(qBadgeView, "translationY", 0f, -ConvertUtils.dp2px(6f), 0f);
animator.setDuration(300);
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (animator.isRunning()) {
return;
}
animator.start();
}
}, 500);
}
}
封装AppCart.java作为辅助类:
public class AppCart {
//购物车
private static List mList;
public static List getCartList() {
if (mList == null) {
mList = new ArrayList<>();
}
if (mList.isEmpty()) {
mList = (List) CacheUtils.getInstance().getSerializable("cacheCart");
if (mList == null) {
mList = new ArrayList<>();
}
}
return mList;
}
/**
* 单个商品数量变化 先改变后传入
*/
public static void onChangeOne(ProductListBean bean) {
if (bean == null) {
return;
}
if (mList == null) {
getCartList();
}
int index;
if (mList.contains(bean)) {
index = mList.indexOf(bean);
mList.get(index).buy_num = bean.buy_num;
if (mList.get(index).buy_num <= 0) {
mList.remove(bean);
}
} else {
mList.add(0, bean);
}
putCartList(mList);
}
/**
* 获得购物车数量
*/
public static int getCartNumber() {
if (getCartList()==null || getCartList().isEmpty()) {
return 0;
}
int number = 0;
for (ProductListBean productBean : mList) {
number += productBean.buy_num;
}
return number;
}
/**
* 写入缓存
*/
public static void putCartList(List cartList) {
mList = cartList;
//发送广播
EventBus.getDefault().post(new CartEvent());
}
/**
* 移除一样商品
*/
public static void onRemove(ProductListBean bean) {
if (bean == null) {
return;
}
bean.buy_num = 0;
mList.remove(bean);
putCartList(mList);
}
/**
* 清除补货清单
*/
public static void clear() {
if (getCartList()==null || getCartList().isEmpty()) {
return;
}
CacheUtils.getInstance().remove("cacheCart");
mList.clear();
}
/**
* 比对数据
* @param list
* @return true有比对 false无比对
*/
public static boolean comparison(List list) {
List listCart = getCartList();
if (list == null || list.size() == 0) {
return false;
}
if (listCart == null || listCart.size() == 0) {
for (ProductListBean productBean : list) {
productBean.buy_num = 0;
}
return true;
}
int index;
for (ProductListBean productBean : list) {
if (listCart.contains(productBean)) {
index = listCart.indexOf(productBean);
productBean.buy_num = listCart.get(index).buy_num;
} else {
productBean.buy_num = 0;
}
}
return true;
}
}
接下来就是最重要的MainActivity.java了:
/**
* Created by LXL on 2017/12/8.
* http://my.csdn.net/lxlyhm
* https://github.com/LXLYHM
* http://www.jianshu.com/u/8fd63a0d4c4c
* 购物车
*/
public class MainActivity extends AddCartActivity {
private RecyclerView mRecyclerView;
private List mList = new ArrayList();
private ProductAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//状态栏全局默认统一成白底黑字
ImmersionBar.with(this).statusBarColor(R.color.colorPrimary).fitsSystemWindows(true).init();
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
mAdapter = new ProductAdapter();
mRecyclerView.setAdapter(mAdapter);
mAdapter.setNewData(mList);
initData();
}
/**
* 加载数据
*/
private void initData() {
new AppData().getData(new CallBackAdapter() {
@Override
public void onSuccess(String object) {
List list = new Gson().fromJson(object, new TypeToken>() {}.getType());
AppCart.comparison(list);
mList = list;
mAdapter.setNewData(mList);
}
@Override
public void onFailure(int code, String message) {
}
@Override
public void onCompleted() {
}
});
}
/**
* 显示状态
*/
public void checkState() {
if (AppCart.getCartNumber() <= 0) {
if (qBadgeView != null) {
qBadgeView.hide(true);
}
} else {
//动画
if (qBadgeView == null) {
View view = findViewById(R.id.containerBageView);
qBadgeView = new QBadgeView(this);
qBadgeView.setGravityOffset(0f, ConvertUtils.dp2px(6f), false).bindTarget(view);
}
qBadgeView.setBadgeNumber(AppCart.getCartNumber());
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(CartEvent event) {
checkState();
}
@Override
protected void onStart() {
super.onStart();
checkState();
}
@Override
protected void onDestroy() {
super.onDestroy();
AppCart.clear();//清除
ImmersionBar.with(this).destroy();
}
}
ProductAdapter.java:
public class ProductAdapter extends BaseQuickAdapter {
public ProductAdapter(){
super(R.layout.item_product);
}
@Override
protected void convert(final BaseViewHolder helper, final ProductListBean item) {
helper.setText(R.id.productsName, item.name);
ImageLoader.getInstance().load(item.cover_image_url, (ImageView) helper.getView(R.id.imgProducts));
final MyEditText etNumber = helper.getView(R.id.et_number);//数量
etNumber.clearFocus();//清除焦点
etNumber.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
etNumber.setCursorVisible(true);// 再次点击显示光标
}
return false;
}
});
etNumber.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!"".equals(s.toString())) {
int buy_num = parseInt(s.toString());
item.buy_num = buy_num;
if (buy_num > 0) {
AppCart.onChangeOne(item);//发送购物车变化
}
if (buy_num == 0){
AppCart.onRemove(item);
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
etNumber.setText(item.buy_num + "");
// 加
helper.getView(R.id.bt_add).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
item.buy_num++;
if (item.buy_num > 0){
EventBus.getDefault().post(new ProductAnimEvent(helper.getView(R.id.imgProducts), item.cover_image_url));
}
etNumber.setText(item.buy_num + "");
}
});
// 减
helper.getView(R.id.bt_float).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (item.buy_num == 0) {
return;
}
item.buy_num--;
etNumber.setText(item.buy_num + "");
}
});
}
}
如果有需要kotlin语言项目的小伙伴们可以留言私信我