二级购物车

购物车的接口

**
     * 购物车接口
     * http://172.17.8.100/ks/product/getCarts?uid=51
     *
     * public static final String ShoppingUrl="http://172.17.8.100/ks/product/";
     */

    @GET("getCarts") //以后用GET请求的话 还需要传入参数用哪个Query吧
    Flowable<ShoppingBean> getShopping(@Query("uid") int uid);

然后OK+Rx+Retrofit

public class RetrofitUtils {

    /**
     * 单例模式
     */
    public static RetrofitUtils retrofitUtils;

    public RetrofitUtils(){

    }

    public static RetrofitUtils getInstance(){
        if (retrofitUtils==null){
            synchronized (RetrofitUtils.class){
                if (retrofitUtils==null){
                    retrofitUtils=new RetrofitUtils();
                }
            }
        }
        return retrofitUtils;
    }
    /**
     * 获取OkHttp
     */
    private static OkHttpClient okHttpClient;

    public static synchronized OkHttpClient getOkHttpClient(){
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {

            }
        });

        okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY))
                .connectTimeout(2000,TimeUnit.SECONDS)
                .readTimeout(2000,TimeUnit.SECONDS)
                .build();

         return okHttpClient;
    }

    /**
     * 获取Retrofit
     */
    private static Retrofit retrofit;


    public static synchronized Retrofit getRetrofit(String url){
         retrofit = new Retrofit.Builder()
                 .baseUrl(url)
                 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                 .addConverterFactory(GsonConverterFactory.create())
                 .client(getOkHttpClient())
                .build();
        return retrofit;
    }

    /**
     * 获取动态权限
     */
    public <T> T  doGet(String url,Class<T> apiService){
        retrofit = getRetrofit(url);
        T t = retrofit.create(apiService);
        return t;
    }


}

然后是MVP
首先是M层

public class ShoppingModel {


    public void getHttpData(int uid){
        ApiService apiService = RetrofitUtils.getInstance().doGet(Api.ShoppingUrl, ApiService.class);

        Flowable<ShoppingBean> shopping = apiService.getShopping(uid);

        shopping.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableSubscriber<ShoppingBean>() {
                    @Override
                    public void onNext(ShoppingBean dataBean) {

                        if (shoppingListener!=null){
                            shoppingListener.onShopping(dataBean);
                        }
                    }
                    @Override
                    public void onError(Throwable t) {
                        //这个要注意 及时打印
                        Log.d("--", "onError: "+t.getMessage());
                    }
                    @Override
                    public void onComplete() {

                    }
                });
    }
    
    /**
     * 接口回调
     */
    public interface onShoppingListener{
        // public void onNext(ShoppingBean.DataBean dataBean) 他们两个类型需要对应上
        void onShopping(/*List<*/ShoppingBean/*> */shoppingData);
    }
    
    onShoppingListener shoppingListener;
    
    public void setShoppingListener(onShoppingListener shoppingListener){
        this.shoppingListener=shoppingListener;
    }
}

然后写V层接口

public interface ShoppingView {

    void getShppingData(ShoppingBean shoppingData);
}

然后P层连接V M

public class ShoppingPresenter extends BasePresenter<ShoppingView> {
    private ShoppingView shoppingView;
    private ShoppingModel shoppingModel;

    public ShoppingPresenter(ShoppingView view){
        this.shoppingView=view;

        shoppingModel=new ShoppingModel();
    }


    public void onReletad(int uid){
        shoppingModel.getHttpData(uid);
        shoppingModel.setShoppingListener(new ShoppingModel.onShoppingListener() {
            @Override
            public void onShopping(ShoppingBean shoppingData) {
                shoppingView.getShppingData(shoppingData);
            }
        });
    }
}

P的抽基类

public abstract class BasePresenter<T> {
    private Reference<T> tReference;

    public void attachView(T t){
        tReference = new WeakReference<>(t);
    }

    public void deatchView(){
        if (tReference!=null){
            tReference.clear();
            tReference=null;
        }
    }
}

然后是适配器 二级购物车需要写两个适配器 每个适配器里都要有接口回调获取选中状态 还需要在bean里面添加一个 boolean isCheck; // 这个是商家选中和未选中状态

首先是商家的适配器


public class ShoopingAdapter extends RecyclerView.Adapter<ShoopingAdapter.MyViewHoder> {
    private Context context;
    private List<ShoppingBean.DataBean> list;

    public ShoopingAdapter(Context context, List<ShoppingBean.DataBean> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public MyViewHoder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(context).inflate(R.layout.shopping_item, viewGroup, false);

        return new MyViewHoder(view);
    }

    @Override  //这个适配器里面的int i 就是商家一级列表对应的下标
    public void onBindViewHolder(@NonNull final MyViewHoder myViewHoder, final int i) {

        myViewHoder.name.setText(list.get(i).getSellerName());
        //设置复选框的选中状态
        myViewHoder.che.setChecked(list.get(i).isCheck());

        myViewHoder.che.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //等下写一个接口回调 参数是下标
                if (cheListener != null) {
                    cheListener.onChe(i, myViewHoder.che.isChecked());
                }
            }
        });

        //使用recycle需要设置布局管理器
        myViewHoder.rec.setLayoutManager(new LinearLayoutManager(context));

        //之后就是创建适配器 使用适配器
        TwoAdapter twoAdapter = new TwoAdapter(context, list.get(i).getList());
        myViewHoder.rec.setAdapter(twoAdapter);

        twoAdapter.setCallbackListener(new TwoAdapter.onCallbackListener() {
            @Override
            public void onChecked(int position, boolean isChecked) {
                //等下写一个接口回调 参数是下标
                if (cheListener != null) {
                    cheListener.onItemChecked(i, position, isChecked);
                }
            }

            @Override
            public void onDelete(int position) {
             //等下写一个接口回调 参数是下标
                if (cheListener != null) {
                    cheListener.onDelete(i,position);
                }
            }
        });

    }

    @Override
    public int getItemCount() {
        return list.size();
    }




    public class MyViewHoder extends RecyclerView.ViewHolder {
        private RecyclerView rec;
        private TextView name;
        private CheckBox che;

        public MyViewHoder(@NonNull View itemView) {
            super(itemView);
            che = itemView.findViewById(R.id.shopping_che);
            name = itemView.findViewById(R.id.shopping_name);
            rec = itemView.findViewById(R.id.shopping_rec);
        }
    }

    /**
     * 接口回调
     */
    public interface onCheListener {
        //item 选中接口回调
        void onChe(int position, boolean isChecked);

        //第一个参数是当前点击的这个二级里面的复选框属于那个商家里面的 所以需要获取商家的那个下标
        //第二个就是他自己位于的下标
        //第三个就是选中状态
        void onItemChecked(int group, int cheid, boolean isChecked);

        //第一个参数还是表达属于哪个商家的
        //第二个是当前自己的下标
        void onDelete(int i,int position);

    }

    onCheListener cheListener;

    public void setCheListener(onCheListener cheListener) {
        this.cheListener = cheListener;
    }


}
对应的布局

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <CheckBox
        android:id="@+id/shopping_che"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"/>
    <TextView
        android:id="@+id/shopping_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:text="111"/>

</LinearLayout>


<android.support.v7.widget.RecyclerView
    android:id="@+id/shopping_rec"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

</android.support.v7.widget.RecyclerView>

然后这个是商品的适配器

public class TwoAdapter extends RecyclerView.Adapter<TwoAdapter.ViewHoder> {

    private Context context;
    private List<ShoppingBean.DataBean.ListBean> list;

    public TwoAdapter(Context context, List<ShoppingBean.DataBean.ListBean> list) {
        this.context = context;
        this.list = list;
    }


    @NonNull
    @Override
    public ViewHoder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(context).inflate(R.layout.shopping_item_two, viewGroup, false);
        return new ViewHoder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHoder viewHoder,final int i) {

        ShoppingBean.DataBean.ListBean resultBean = list.get(i);
        int price = resultBean.getPrice();

        viewHoder.name.setText(resultBean.getSubhead());
        viewHoder.price.setText("¥" + price);
        Glide.with(context).load(resultBean.getImages()).into(viewHoder.image);

        //根据我记录的状态,改变勾选
        viewHoder.che.setChecked(list.get(i).isChecked());

        //商品复选框点击
        viewHoder.che.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (callbackListener != null) {
                    callbackListener.onChecked(i,viewHoder.che.isChecked());
                }
            }
        });

        //加减器方法
        viewHoder.item.setData(this, list, i);

        //商品数量改变  这个等下做
        viewHoder.item.setNumChangeListener(new GroupLayout.onNumChangeListener() {
            @Override
            public void changeNum() {
                if (callbackListener != null) {
                    //callbackListener.onChecked(i, viewHolder.che.isChecked());
                }
            }
        });


    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class ViewHoder extends RecyclerView.ViewHolder {
        private final CheckBox che;
        private final SimpleDraweeView image;
        private final TextView name,price;
        private final GroupLayout item;

        public ViewHoder(@NonNull View itemView) {
            super(itemView);
            che=itemView.findViewById(R.id.shopping_item_che);
            image=itemView.findViewById(R.id.shopping_item_image);
            name=itemView.findViewById(R.id.shopping_item_name);
            price=itemView.findViewById(R.id.shopping_item_price);
            item=itemView.findViewById(R.id.shopping_group_item);

        }
    }


    public interface onCallbackListener {
        //item 选中接口回调
        void onChecked(int position, boolean isChecked);

        //删除回调
        void onDelete(int position);
    }

    public onCallbackListener callbackListener;

    public void setCallbackListener(onCallbackListener callbackListener) {
        this.callbackListener = callbackListener;
    }

}

对应的布局


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:id="@+id/left_layout"
                android:layout_toLeftOf="@+id/shopping_group_item"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <CheckBox
                    android:layout_gravity="center"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/shopping_item_che"
                    />

                <com.facebook.drawee.view.SimpleDraweeView
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    android:id="@+id/shopping_item_image"
                    android:layout_marginLeft="8dp"
                    android:layout_marginTop="8dp"
                    android:layout_marginBottom="8dp"
                    />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
                    <TextView
                        android:id="@+id/shopping_item_name"
                        android:text="商品标题商品标题商品标题商品标题商品标题"
                        android:layout_margin="10dp"
                        android:lines="2"
                        android:ellipsize="end"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        />

                    <TextView
                        android:id="@+id/shopping_item_price"
                        android:text="价格"
                        android:textSize="14sp"
                        android:textColor="#ff00"
                        android:layout_margin="10dp"
                        android:lines="2"
                        android:ellipsize="end"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        />

                </LinearLayout>

            </LinearLayout>

            <com.example.moni2.view.GroupLayout
                android:id="@+id/shopping_group_item"
                android:layout_centerVertical="true"
                android:layout_alignParentRight="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

            </com.example.moni2.view.GroupLayout>

        </RelativeLayout>
    </LinearLayout>

然后商品的加减器是自定义的View
自定义View里面也有接口回调的方法 下面是主要代码

public class GroupLayout extends LinearLayout implements View.OnClickListener{

    private int number = 1;
    private TextView num_goods;
    private TwoAdapter queryAdapter;
    private List<ShoppingBean.DataBean.ListBean> list;
    private int i;


    public GroupLayout(Context context) {
        super(context);
    }

    public GroupLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.group_layout, this);
        //控件
        TextView minus_goods = findViewById(R.id.shopping_item_jian);
        TextView add_goods = findViewById(R.id.shopping_item_jia);
        num_goods = findViewById(R.id.shopping_item_shu);
        num_goods.setText(number + "");

        /**
         * 设置点击事件监听
         */
        minus_goods.setOnClickListener(this);
        add_goods.setOnClickListener(this);


    }

    public GroupLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {

            case R.id.shopping_item_jia://加
                number++;
                num_goods.setText(number + "");
                list.get(i).setNum(number);
                numChangeListener.changeNum();
                queryAdapter.notifyItemChanged(i);
                break;
            case R.id.shopping_item_jian://减
                if (number > 1) {
                    number--;

                } else {
                    Toast.makeText(getContext(), "不能再少了", Toast.LENGTH_SHORT).show();
                }
                num_goods.setText(number + "");
                list.get(i).setNum(number);
                numChangeListener.changeNum();
                queryAdapter.notifyItemChanged(i);
                break;
        }


    }

    public void setData(TwoAdapter queryAdapter, List<ShoppingBean.DataBean.ListBean> list, int i) {
        this.list = list;
        this.queryAdapter = queryAdapter;
        this.i = i;
        number = list.get(i).getNum();
        num_goods.setText(this.number + "");
    }


    /**
     * 接口回调
     */
    public interface onNumChangeListener {
        void changeNum();
    }

    public onNumChangeListener numChangeListener;

    public void setNumChangeListener(onNumChangeListener numChangeListener) {
        this.numChangeListener = numChangeListener;
    }
}

对应的布局文件


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="14dp"
        android:layout_marginBottom="24dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/shopping_item_jian"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginRight="3dp"
            android:text="-"
            android:textColor="#666666"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/shopping_item_shu"
            android:layout_width="31dp"
            android:layout_height="18dp"
            android:layout_gravity="bottom"
            android:gravity="center"
            android:background="#ddd"
            android:maxLength="2"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:text="0"
            android:textColor="#666666"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/shopping_item_jia"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:layout_gravity="bottom"
            android:layout_marginLeft="3dp"
            android:layout_marginRight="10dp"
            android:text="+"
            android:textColor="#666666"
            android:textSize="16sp" />
    </LinearLayout>

然后是主要的代码


public class FragmentTwo extends BaseFragment<ShoppingPresenter> implements ShoppingView {


    @BindView(R.id.shopp_rec)
    RecyclerView shoppRec;
    @BindView(R.id.shopp_che)
    CheckBox shoppChe;
    @BindView(R.id.shopp_price)
    TextView shoppPrice;
    @BindView(R.id.shopp_btn)
    Button shoppBtn;
    Unbinder unbinder;
    private ShoppingPresenter shoppingPresenter;
    private ShoopingAdapter shoopingAdapter;
    private List<ShoppingBean.DataBean> result;
    private int uid = 51;

    @Override
    protected int getLayout() {
        return R.layout.fragmenttwo;
    }

    @Override
    protected void initdata() {

        /**
         * 全选点击事件
         */
        shoppChe.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //checkAll(shoppChe.isChecked());
                //点击结算按钮处的全选/反选按钮
                for (int i = 0; i < result.size(); i++) {
                    //将一级列表复选框状态改变为选中或未选中
                    result.get(i).setCheck(shoppChe.isChecked());
                    List<ShoppingBean.DataBean.ListBean> list = result.get(i).getList();
                    for (int i1 = 0; i1 < list.size(); i1++) {
                        //将二级条目复选框状态改变为选中或未选中
                        list.get(i1).setChecked(shoppChe.isChecked());
                    }
                }

                setPrices();
            }
        });

    }

    private boolean checkAll(int i /* 接受一个下标*/) {

        List<ShoppingBean.DataBean.ListBean> list = result.get(i).getList();

        for (int i1 = 0; i1 < list.size(); i1++) {

            boolean checked = list.get(i1).isChecked();
            //if(checked) //这个是判断true的条件写法
            if(!checked){
                //false 的一个条件
                return false;
            }

        }
        return true;
    }
    /**
     * 价钱的方法
     */
    private void setPrices() {
        //这个选中状态需要加入两个了,一个是一级的那个复选框状态 另一个是子列表的复选框状态
        double priceAll = 0.0;
        int num = 0;

        //循环集合判断选中状态
        for (int i = 0; i < result.size(); i++) {

            List<ShoppingBean.DataBean.ListBean> list = result.get(i).getList();

            for (int i1 = 0; i1 < list.size(); i1++) {
                //判断二级条目中是否有选中
                if (list.get(i1).isChecked()) {
                    priceAll += list.get(i1).getPrice() * list.get(i1).getNum();
                    num += list.get(i1).getNum();
                }
            }
        }

        shoppPrice.setText("合计:" + priceAll);
        shoppBtn.setText("去结算(" + num + ")");

        //刷新适配器
        setAdapter();

    }

    private void setAdapter() {

        //就是如果这个适配器对象为空创建 和设置接口回调
        if (shoopingAdapter == null) {
            shoopingAdapter = new ShoopingAdapter(getActivity(), result);
            shoppRec.setAdapter(shoopingAdapter);
            shoopingAdapter.setCheListener(new ShoopingAdapter.onCheListener() {
                @Override
                public void onChe(int position, boolean isChecked) {
                    //改变当前一级列表的选中状态
                    result.get(position).setCheck(isChecked);

                    List<ShoppingBean.DataBean.ListBean> list = result.get(position).getList();

                    for (int i = 0; i < list.size(); i++) {
                        list.get(i).setChecked(isChecked);
                    }
                    //计算价格
                    setPrices();
                }

                @Override
                public void onItemChecked(int group, int cheid, boolean isChecked) {

                    //修改状态
                    result.get(group).getList().get(cheid).setChecked(isChecked);

                    boolean b = checkAll(group);

                    //如果 b 为true 表示这个商家里面所有的子条目都是选中状态 所以让商家的复选框为选中状态
                    if(b){
                        result.get(group).setCheck(true);
                    } else {
                        result.get(group).setCheck(false);
                    }

                    //调用计算价钱
                    setPrices();
                }

                @Override
                public void onDelete(int i, int position) {
                    result.get(i).getList().remove(position);
                    //调用计算价钱
                    setPrices();
                }
            });

        } else {
            //如果有这个对象的话,不创建只需要刷新适配器就行了
            shoopingAdapter.notifyDataSetChanged();
        }
    }


    @Override
    protected void intoview(View view) {
        unbinder = ButterKnife.bind(this, view);
        shoppRec.setLayoutManager(new LinearLayoutManager(getContext()));
    }

    @Override
    protected ShoppingPresenter getPresenter() {
        shoppingPresenter = new ShoppingPresenter(this);
        //忘记调用请求网络的方法了
        shoppingPresenter.onReletad(uid);
        return shoppingPresenter;
    }

    //
    @Override
    public void getShppingData(ShoppingBean shoppingData) {

        result = shoppingData.getData();
        //吧第一条空数据删除
        result.remove(0);
        Log.d("--", "getShppingData: " + result.size());

        setAdapter();
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}

对应的布局文件


    <android.support.v7.widget.RecyclerView
        android:id="@+id/shopp_rec"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="8"
        android:layout_marginTop="20dp">
    </android.support.v7.widget.RecyclerView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        >
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="5"
            android:gravity="center">

            <CheckBox
                android:id="@+id/shopp_che"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="全选" />

        </LinearLayout>


        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="15"
            android:orientation="horizontal"
            android:gravity="center_vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp" />

            <TextView
                android:id="@+id/shopp_price"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="¥0.0"
                android:textSize="17sp"
                android:textColor="#CF2424"/>

        </LinearLayout>



        <Button
            android:id="@+id/shopp_btn"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="5"
            android:gravity="center"
            android:background="#FFFE3AA9"
            android:text="去结算"
            android:textColor="#ffffff"
            android:textSize="15sp" />

    </LinearLayout>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值