年底忙碌起來便擠不出時間更新筆記文章了还惠,趁今天周末抽空把之前的功能筆記補齊O(∩_∩)O哈哈~
記錄到這個功能我首先要感謝一下我目前的老大對我的幫助糙申,一位英俊瀟灑風(fēng)流倜儻陽光幽默精通各大代碼域的帥小伙guthub:https://github.com/KnifeStone
一.概述 :
EventBus是針對Android優(yōu)化的發(fā)布/訂閱事件總線。主要是替代Intent/Handler/BroadCast在Fragment/Activity/Service線程之間傳遞消息嚣伐。開銷小,代碼更優(yōu)雅,將發(fā)送者和接收者解耦策严。
二.推薦:
針EventBus的簡單用法推薦(作者寫得通俗易懂)
http://blog.csdn.net/harvic880925/article/details/40660137
更深入了解EventBus推薦
http://www.reibang.com/p/31e3528ca7e5
(1). EventBus官網(wǎng)地址
(2). EventBus github地址
(3). EventBus 3.0的用法詳解
三.實現(xiàn)步驟:
按照以往的慣例先上效果圖:
看完效果圖可以知道實現(xiàn)添加購物車分為幾部分:
首先先簡單寫一個產(chǎn)品列表,數(shù)據(jù)是存儲在七牛云上面的臨時數(shù)據(jù)饿敲,先拿來用妻导。
github下載地址,歡迎star:https://github.com/LXLYHM/EventBusAddShoppingCart/blob/master/README.md
代碼注釋比較詳細(xì)怀各,感興趣的小伙伴可以下載看看倔韭,下面直接上干貨,就不多解釋廢話了
1.網(wǎng)絡(luò)框架:是自封裝的一個非常簡單的Retrofit2網(wǎng)絡(luò)框架
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里面注冊關(guān)閉好EventBus和實現(xiàn)加入購物車動畫給MainActivity.java繼承:
public abstract class AddCartActivity extends AppCompatActivity {
protected QBadgeView qBadgeView = null;//購物車數(shù)量紅點
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);
}
//發(fā)送消息線程
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(ProductAnimEvent event) {
if (qBadgeView == null) {
return;
}
View view = event.view;
//獲取商品坐標(biāo)
int[] goodsPoint = new int[2];
view.getLocationInWindow(goodsPoint);
//獲取購物車坐標(biāo)
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<ProductListBean> mList;
public static List<ProductListBean> getCartList() {
if (mList == null) {
mList = new ArrayList<>();
}
if (mList.isEmpty()) {
mList = (List<ProductListBean>) CacheUtils.getInstance().getSerializable("cacheCart");
if (mList == null) {
mList = new ArrayList<>();
}
}
return mList;
}
/**
* 單個商品數(shù)量變化 先改變后傳入
*/
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);
}
/**
* 獲得購物車數(shù)量
*/
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<ProductListBean> cartList) {
mList = cartList;
//發(fā)送廣播
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();
}
/**
* 比對數(shù)據(jù)
* @param list
* @return true有比對 false無比對
*/
public static boolean comparison(List<ProductListBean> list) {
List<ProductListBean> 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.reibang.com/u/8fd63a0d4c4c
* 購物車
*/
public class MainActivity extends AddCartActivity {
private RecyclerView mRecyclerView;
private List<ProductListBean> mList = new ArrayList();
private ProductAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//狀態(tài)欄全局默認(rèn)統(tǒng)一成白底黑字
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();
}
/**
* 加載數(shù)據(jù)
*/
private void initData() {
new AppData().getData(new CallBackAdapter<String>() {
@Override
public void onSuccess(String object) {
List<ProductListBean> list = new Gson().fromJson(object, new TypeToken<List<ProductListBean>>() {}.getType());
AppCart.comparison(list);
mList = list;
mAdapter.setNewData(mList);
}
@Override
public void onFailure(int code, String message) {
}
@Override
public void onCompleted() {
}
});
}
/**
* 顯示狀態(tài)
*/
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<ProductListBean, BaseViewHolder> {
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);//數(shù)量
etNumber.clearFocus();//清除焦點
etNumber.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
etNumber.setCursorVisible(true);// 再次點擊顯示光標(biāo)
}
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);//發(fā)送購物車變化
}
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語言項目的小伙伴們可以留言私信我