今天来练习一下二级列表购物车,效果如下图
整体效果就是这样,布局呢,不是很好看,建议大家可以只参考逻辑代码。
首先,导依赖
//Butterknife:根据反射注入框架
implementation ‘com.jakewharton:butterknife:8.8.1’
annotationProcessor ‘com.jakewharton:butterknife-compiler:8.8.1’
//okgo
//必须使用
implementation ‘com.lzy.net:okgo:3.0.4’
//Brvah:RecyclerView快速开发框架
implementation ‘com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30’
//SmartRefreshLayout
implementation ‘com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-19’
implementation ‘com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-19’
//没有使用特殊Header,可以不加这行
//图片加载框架
implementation ‘com.github.bumptech.glide:glide:4.8.0’
annotationProcessor ‘com.github.bumptech.glide:compiler:4.8.0’
implementation ‘com.android.support:design:28.+’
//gson解析
implementation ‘com.google.code.gson:gson:2.8.5’
再搭建好MVP,下面我们就可以开始步入正题
V层
package ws.com.mnyk;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import com.google.gson.Gson;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class Frag_shopping extends Fragment implements IContract.IView {
@BindView(R.id.rv_shopping)
RecyclerView rvShopping;
@BindView(R.id.cb_qx)
CheckBox cbQx;
@BindView(R.id.button)
Button button;
@BindView(R.id.tv_price)
TextView tvPrice;
Unbinder unbinder;
private IContract.IPresenter presenter;
private MyShoopingAdapter shoopingAdapter;
private List<JsonBean.DataBean> data;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_shopping, null);
unbinder = ButterKnife.bind(this, view);
presenter = new Presenter();
presenter.attahView(this);
presenter.requestData();
return view;
}
@Override
public void showData(String json) {
//接收到M层传来的json 在这里我是在V层解析
cbQx.setOnCheckedChangeListener(null);
Gson gson = new Gson();
JsonBean jsonBean = gson.fromJson(json, JsonBean.class);
data = jsonBean.getData();
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
rvShopping.setLayoutManager(manager);
shoopingAdapter = new MyShoopingAdapter(R.layout.frag_shopping_chiled, data);
rvShopping.setAdapter(shoopingAdapter);
cbQx.setOnCheckedChangeListener(null);
shoopingAdapter.setOnShoppingItemChildClickListener(new MyShoopingAdapter.OnShoppingItemChildClickListener() {
@Override
public void onCallbask() {
boolean mn = true;
for (int i = 0; i < data.size(); i++) {
boolean businessChecked = data.get(i).getBusinessChecked();
mn = mn & businessChecked;
for (int j = 0; j < data.get(i).getList().size(); j++) {
boolean goodsChecked = data.get(i).getList().get(j).getGoodsChecked();
mn = mn & goodsChecked;
}
}
cbQx.setChecked(mn);
num();
}
});
}
//总价计算
private void num() {
double nums = 0;
for (int i = 0; i < data.size(); i++) {
for (int j = 0; j < data.get(i).getList().size(); j++) {
if (data.get(i).getList().get(j).getGoodsChecked() == true) {//getGoodsChecked是二级列表的状态 如果等于true ,就实现下面计算内容
double price = data.get(i).getList().get(j).getPrice();
int num = data.get(i).getList().get(j).getNum();
double v = price * num;
nums = v + nums;
}
}
}
tvPrice.setText("¥" + nums);
}
//全选按钮的点击事件
@OnClick(R.id.cb_qx)
public void onViewClicked() {
for (int i=0;i<data.size();i++){
data.get(i).setBusinessChecked(cbQx.isChecked());
for (int j=0;j<data.get(i).getList().size();j++){
data.get(i).getList().get(j).setGoodsChecked(cbQx.isChecked());
}
}
//适配器刷新
shoopingAdapter.notifyDataSetChanged();
//调用计算总和
num();
}
@Override
public void onDestroyView() {
super.onDestroyView();
presenter.decathView(this);
}
}
P层就略过直接看M层
package ws.com.mnyk;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;
public class Model implements IContract.IModel {
@Override
public void conresponse(final Callbask callbask) {
String urlString = Content.SHOPPINGCART_URL;
//这里我用的是OkGo获取网络数据
OkGo.<String>get(urlString).execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
String json = response.body().toString();
callbask.response(json);
}
});
}
}
适配器里面我是用的BaseQuickAdapter,其中呢,我也用了接口回调传递所需要的信息
一级父类适配器
package ws.com.mnyk;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
public class MyShoopingAdapter extends BaseQuickAdapter<JsonBean.DataBean,BaseViewHolder> {
private int L;
private MyGoodsAdapter goodsAdapter;
OnShoppingItemChildClickListener onShoppingItemChildClickListener;
public void setOnShoppingItemChildClickListener(OnShoppingItemChildClickListener onShoppingItemChildClickListener) {
this.onShoppingItemChildClickListener = onShoppingItemChildClickListener;
}
public interface OnShoppingItemChildClickListener{
public void onCallbask();
}
public MyShoopingAdapter(int layoutResId, @Nullable List<JsonBean.DataBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, final JsonBean.DataBean item) {
final CheckBox cb_shangjia = helper.getView(R.id.cb_shangjia);
RecyclerView rv_goods = helper.getView(R.id.rv_goods);
helper.setText(R.id.cb_shangjia,item.getSellerName());
cb_shangjia.setOnCheckedChangeListener(null);
cb_shangjia.setChecked(item.getBusinessChecked());
final List<JsonBean.DataBean.ListBean> list = item.getList();
LinearLayoutManager manager=new LinearLayoutManager(mContext,LinearLayoutManager.VERTICAL,false);
rv_goods.setLayoutManager(manager);
goodsAdapter = new MyGoodsAdapter(R.layout.frag_shopping_chiled_item,list);
rv_goods.setAdapter(goodsAdapter);
goodsAdapter.setOnGoodsItemChildClickListener(new MyGoodsAdapter.OnGoodsItemChildClickListener() {
@Override
public void onCallbask() {
boolean mn =true;
for (int i=0;i<item.getList().size();i++){
boolean goodsChecked = item.getList().get(i).getGoodsChecked();
mn= mn &goodsChecked;
}
cb_shangjia.setChecked(mn);
goodsAdapter.notifyDataSetChanged();
onShoppingItemChildClickListener.onCallbask();
}
});
//父类全选按钮的实现
cb_shangjia.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int i=0;i<item.getList().size();i++){
item.getList().get(i).setGoodsChecked(cb_shangjia.isChecked());
}
item.setBusinessChecked(cb_shangjia.isChecked());
goodsAdapter.notifyDataSetChanged();
onShoppingItemChildClickListener.onCallbask();
}
});
}
}
二级子类适配器
package ws.com.mnyk;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
public class MyGoodsAdapter extends BaseQuickAdapter<JsonBean.DataBean.ListBean,BaseViewHolder> {
OnGoodsItemChildClickListener onGoodsItemChildClickListener;
public void setOnGoodsItemChildClickListener(OnGoodsItemChildClickListener onGoodsItemChildClickListener) {
this.onGoodsItemChildClickListener = onGoodsItemChildClickListener;
}
public interface OnGoodsItemChildClickListener{
public void onCallbask();
}
public MyGoodsAdapter(int layoutResId, @Nullable List<JsonBean.DataBean.ListBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, final JsonBean.DataBean.ListBean item) {
helper.setText(R.id.tv_goodsPrice,"¥:"+item.getPrice());
helper.setText(R.id.tv_goodsTitle,item.getTitle());
ImageView iv_goodsIcon = helper.getView(R.id.iv_goodsIcon);
final String images = item.getImages();
String[] split = images.split("\\|");
Glide.with(mContext).load(split[0]).into(iv_goodsIcon);
final CheckBox ck_goods = helper.getView(R.id.ck_goods);
ck_goods.setOnCheckedChangeListener(null);
ck_goods.setChecked(item.getGoodsChecked());
ck_goods.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
item.setGoodsChecked(isChecked);
onGoodsItemChildClickListener.onCallbask();
}
});
//加减器的实现
NumView num_view = helper.getView(R.id.num_view);
num_view.setOnViewClickListener(new NumView.OnViewClickListener() {
@Override
public void onadd(int number) {
item.setNum(number);
onGoodsItemChildClickListener.onCallbask();
}
@Override
public void onjian(int number) {
item.setNum(number);
onGoodsItemChildClickListener.onCallbask();
}
});
}
}
最后不要忘记我们的加减器所有布局都在下面
package ws.com.mnyk;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class NumView extends LinearLayout implements View.OnClickListener {
private final TextView tv_number;
public NumView(Context context, AttributeSet attrs) {
super(context, attrs);
View inflate = LayoutInflater.from(context).inflate(R.layout.jjq, this);
Button btn_add = inflate.findViewById(R.id.btn_add);
Button btn_decrease = inflate.findViewById(R.id.btn_decrease);
tv_number = inflate.findViewById(R.id.tv_number);
btn_add.setOnClickListener(this);
btn_decrease.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String string = tv_number.getText().toString();
int number = Integer.parseInt(string);
switch (v.getId()){
case R.id.btn_add:
number=number+1;
tv_number.setText(String.valueOf(number));
onViewClickListener.onadd(number);
break;
case R.id.btn_decrease:
number=number-1;
if (number<1){
number=1;
tv_number.setText(String.valueOf(number));
}
tv_number.setText(String.valueOf(number));
onViewClickListener.onjian(number);
break;
}
}
OnViewClickListener onViewClickListener;
public void setOnViewClickListener(OnViewClickListener onViewClickListener) {
this.onViewClickListener = onViewClickListener;
}
public interface OnViewClickListener{
public void onadd(int number);
public void onjian(int number);
}
}
布局
这个布局要实现的是外部包裹层和下面全选,总价格 ,去结算按钮的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_shopping"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<CheckBox
android:id="@+id/cb_qx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="CheckBox"
android:layout_alignParentLeft="true" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:text="去结算"
android:layout_alignParentRight="true" />
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginStart="114dp"
android:layout_marginLeft="114dp"
android:text="0.0" />
</RelativeLayout>
</LinearLayout>
一级列表布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<CheckBox
android:id="@+id/cb_shangjia"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="acacece"
/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_goods"
android:layout_width="match_parent"
android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView>
</LinearLayout>
二级列表布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="340dp"
android:layout_height="120dp"
android:background="@drawable/frag_style"
android:orientation="horizontal"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ck_goods"
android:layout_margin="@dimen/dp_10"
android:layout_centerVertical="true"
/>
</RelativeLayout>
<ImageView
android:layout_gravity="center_vertical"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/ic_launcher_round"
android:id="@+id/iv_goodsIcon"
android:paddingLeft="5dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_goodsTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:maxEms="15"
android:maxLines="2"
android:paddingLeft="5dp"
android:text="商品名称"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_goodsPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:gravity="center"
android:hint="商品价格" />
//自定义view实现加减器布局
<ws.com.mnyk.NumView
android:id="@+id/num_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
></ws.com.mnyk.NumView>
</LinearLayout>
</LinearLayout>
其中,我用的shape绘制的很简单的边框
shape
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="2dp"
android:color="#cccccc"></stroke>
<solid
android:color="@android:color/transparent"/>
<corners android:radius="8dp"></corners>
</shape>
还有不要忘记我们的加减器的一个布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_40"
android:orientation="horizontal"
>
<Button
android:id="@+id/btn_decrease"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:padding="@dimen/dp_10"
android:text="-"
/>
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:inputType="number"
android:text="1"
/>
<Button
android:id="@+id/btn_add"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:padding="@dimen/dp_10"
android:text="+"
/>
</LinearLayout>