Android 仿京东商城购物车及源码

产品需求和京东商城购物车类似,需求如下:店铺不能跨店结算,仅支持单店结算,单店铺下商品侧滑删除商品,如果单店铺下商品全部删除,需要删除该店铺,店铺的单个商铺库存不足或者商品下架状态不支持选择,商品的数量加减和删除商品都要求调用接口加减删除,大致效果如下

很多界面操作都涉及到刷新UI,这些操作呢我又不想把他们累赘的放在Adapter或者Activity里操作,我的思路是把所有功能定义到interface,通过Imp具体操作Bean,如果需要刷新notifyRefrsh就好。

首先定义好店铺ShopBean

再定义商品GoodsBean

接着我们来定义我们功能性接口,例如购物车加减全选单选之类的,定义函数见下图

见名知其意,这里不细说(之后上传的资源文件有详细注释),功能函数定好了我们还需要回调接口:OnUpdateGoodsCountListener、OnDeleteGoodsListener、OnRefreshListener,前两个用于调用服务器接口响应结果回调到adapter修改购物车数量或者删除商品使用,当功能性操作需要刷新ui通过delegate持有的OnRefreshListener刷新UI

接下来我们定义ShopGoodsDelegate 实现接口 OnShopGoodsListener,adapter的具体操作便可以通过ShopGoodsDelegate代理(具体函数实现逻辑请自行参考上传的资源文件)

使用ShopGoodsDelegate需要注意,如果服务器返回的goodsBean不含shopId字段可以用synShopId函数给他造一个,伪代码块调用如下

     class MainActivity : AppCompatActivity(), OnRefreshListener {
        //---------------------
        shopGoodsDelegate = ShopGoodsDelegate.instance
        shopGoodsDelegate.init(mList, this)
        mAdapter = BuyCarShopAdapter(mList)
        mAdapter!!.delegate = shopGoodsDelegate

        shopRecyclerView.apply {
            layoutManager = LinearLayoutManager(context);
            adapter = mAdapter
            onRefresh()
        }
       //---------------------
        initRecyclerView()
}

编写adapter之前我们需要引入两个第三方库,尽量别重复造轮子:侧滑删除和万能Adapter适配器

    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'
    implementation 'com.yanzhenjie.recyclerview:x:1.3.2'

由于是recyclerView嵌套,两个adapter必须的,这里以ShopAdapter的全选和取消全选为例做一个逻辑说明:如果商店下的所有商品只要有一个可以选择,商店视为可以全选或者全部取消,能选择商店的情况:如果商店下的任何一个商品是选中状态,商店则为选中,如果都没选中商品则商店为未选中状态,点击checkbox显示不同的图标,通过enable控制是否可以点击

override fun convert(holder: BaseViewHolder, item: ShopBean) {
        holder.setIsRecyclable(false)
        holder.itemView.apply {

           ---------------------------------------此处省略-----------------------------------------------

            when(delegate?.hasEnable(item.goodsList!!)){
                true ->{
                    shopCheckBox.isEnabled = true
                    when(delegate?.isSelectShop(item)){
                        true  ->{shopCheckBox.setImageResource(R.mipmap.app_ic_checked_true)}
                        false ->{shopCheckBox.setImageResource(R.mipmap.app_ic_checked_false)}
                    }
                }
                false ->{
                    shopCheckBox.isEnabled = false
                    shopCheckBox.setImageResource(R.mipmap.app_ic_checked_click_false)
                }
            }

            shopCheckBox.setOnClickListener{
                delegate?.onClickShop(item)
            }

        }
    }

像侧滑删除、购物车数量加减这些都不是可以直接操作的,需要调用服务器接口,根据callback listener选择修改

swipeRecyclerView.setOnItemMenuClickListener { menuBridge, adapterPosition ->

            item.goodsList?.get(adapterPosition)?.let {
                delegate?.deleteGoods(it,object: OnDeleteGoodsListener {
                    override fun onDeleteSuccess() {
                        delegate?.onDeleteGoods(adapterPosition,item, data as ArrayList<ShopBean>)
                    }

                    override fun onDeleteFinish() {
                        menuBridge?.closeMenu()
                    }

                })
            }
        }

至于购物车BuyCarCountView自定义的组合控件就比较简单了editText添加TextWatcher,输入一位数为0自动改为1,输入多位数自动去掉首位0,每个字符变化比较goodsBean 记录的count不同就请求接口修改数量,修改失败做回退,加减按钮同理。

这里就提两点:如果需要控制加减Enable显示不同图标和提示语需要自己比较stock库存,如果出现EditText焦点乱跳,下面相关操作可以了解一下


   android:focusable="true"
   android:focusableInTouchMode="true"
   
    holder.setIsRecyclable(false)
        

编辑框手动修改数据,我这里仅仅刷新了activity的总价格,并没有刷新adapter(否则焦点会出bug),所以这里我需要监听键盘消失了刷新一次adapter,这样就避免了焦点问题,activity设置inputMode

 android:windowSoftInputMode="adjustResize"

//activity调用(KeyboardChangeListener资源文件内定义类非系统自带)
KeyboardChangeListener(this).setKeyBoardListener(object :
            KeyboardChangeListener.KeyBoardListener {
            override fun onKeyboardChange(isShow: Boolean, keyboardHeight: Int) {
                if(!isShow){
                    onRefresh()
                }
            }

        })

为什么这样就可以监听到键盘隐藏消失了呢?你可以了解一下view!!.viewTreeObserver.addOnGlobalLayoutListener和输入模式,这里不细说了自行科普

资源地址: https://gitee.com/analyzesystem/shopping_car

<?xml version="1.0" encoding="UTF-8"?> -<LinearLayout android:background="@drawable/aaa" android:weightSum="1" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:layout_height="153dp" android:layout_width="198dp" android:id="@+id/imageView1" android:src="@drawable/xitongji"> </ImageView> -<LinearLayout android:weightSum="1" android:layout_height="32dp" android:layout_width="234dp" android:orientation="horizontal" android:layout_weight="0.23"> <ImageButton android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/jian" android:src="@drawable/jianjian"> </ImageButton> -<EditText android:layout_height="wrap_content" android:layout_width="39dp" android:id="@+id/jishu" android:layout_weight="0.34"> <requestFocus/> </EditText> <ImageButton android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/jia" android:src="@drawable/jiajia"> </ImageButton> </LinearLayout> -<LinearLayout android:weightSum="1" android:layout_height="30dp" android:layout_width="83dp" android:orientation="horizontal"> <TextView android:layout_height="match_parent" android:layout_width="wrap_content" android:id="@+id/jiagequding" android:text="单价:"/> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/jiage" android:text="45"/> </LinearLayout> -<LinearLayout android:weightSum="1" android:layout_height="wrap_content" android:layout_width="210dp" android:orientation="horizontal" android:layout_weight="0.09"> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/zongji" android:text="总计:"> </TextView> <EditText android:layout_height="wrap_content" android:layout_width="56dp" android:id="@+id/editTextzongji"> </EditText> </LinearLayout> -<LinearLayout android:weightSum="1" android:layout_height="wrap_content" android:layout_width="190dp" android:orientation="horizontal"> <Button android:layout_height="match_parent" android:layout_width="wrap_content" android:id="@+id/gouwuquding" android:text="确定购买"> </Button> <Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/gouwuquxiao" android:text="取消购买"> </Button> </LinearLayout> </LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值