购物车的接口
**
* 购物车接口
* 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>