购物车 详情
第一步 依赖权限
implementation ‘com.google.code.gson:gson:2.8.5’
implementation ‘com.squareup.okhttp3:okhttp:3.7.0’
implementation ‘com.squareup.okio:okio:1.12.0’
implementation ‘com.jakewharton:butterknife:8.6.0’
annotationProcessor ‘com.jakewharton:butterknife-compiler:8.6.0’
implementation ‘com.android.support:recyclerview-v7:28.0.0’
implementation ‘com.github.bumptech.glide:glide:4.8.0’
implementation ‘com.android.support:support-v4:28.0.0’
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
第二步 网络封装
public class HttpUtils {
private OkHttpClient client;
private static HttpUtils instance;
public Handler handler=new Handler();
//拦截器
private Interceptor getAppInterceptor(){
Interceptor interceptor=new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request=chain.request();
Log.e("+++++++++++++++",“拦截前”);
Response response=chain.proceed(request);
Log.e("+++++++++++++++",“拦截后”);
return response;
}
};
return interceptor;
}
//耗时操作
private HttpUtils(){
File file=new File(Environment.getExternalStorageDirectory(),“cachell”);
client=new OkHttpClient().newBuilder()
.readTimeout(3000,TimeUnit.SECONDS)
.connectTimeout(3000,TimeUnit.SECONDS)
.addInterceptor(getAppInterceptor())
.cache(new Cache(file,10*1024))
.build();
}
//单例模式
public static HttpUtils getInstance(){
if (instance==null){
synchronized (HttpUtils.class){
instance = new HttpUtils();
}
}
return instance;
}
public void doGet(String url, final Class clazz, final NetCallBack netCallBack){
final Request request = new Request.Builder().get().url(url).build();
final Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
netCallBack.OnFailure(e);
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String s=response.body().string();
Gson gson=new Gson();
final Object oj = gson.fromJson(s, clazz);
handler.post(new Runnable() {
@Override
public void run() {
netCallBack.OnSuccess(oj);
}
});
}
});
}
public interface NetCallBack{
void OnSuccess(Object oj);
void OnFailure(Exception e);
}
}
MVP框架
Model
public class ShopModel implements IShopModel{
@Override
public void getData(String url, final Cteanview cteanview) {
HttpUtils.getInstance().doGet(url,CartBean.class, new HttpUtils.NetCallBack() {
@Override
public void OnSuccess(Object oj) {
cteanview.success(oj);
}
@Override
public void OnFailure(Exception e) {
cteanview.Fuils();
}
});
}
}
model接口
public interface IShopModel {
void getData(String url,Cteanview cteanview);
interface Cteanview{
void success(Object data);
void Fuils();
}
}
Presenter
public class ShopPresenter implements IShopPresenter{
MainActivity mView;
private final ShopModel shopModel;
String url=“http://www.zhaoapi.cn/product/getCarts?uid=71”;
public ShopPresenter(MainActivity mView){
this.mView=mView;
shopModel = new ShopModel();
}
@Override
public void getModelData() {
shopModel.getData(url, new IShopModel.Cteanview() {
@Override
public void success(Object data) {
mView.getViewData(data);
}
@Override
public void Fuils() {
}
});
}
}
Presenter 接口
public interface IShopPresenter {
void getModelData();
}
View
public interface ShopView {
void getViewData(Object data);
}
将数据传到List集合
商家适配器
public class CarAdapter1 extends RecyclerView.Adapter<CarAdapter1.CarHolder> {
private final Context context;
private final List<CartBean.DataBean> mList;
private final LayoutInflater from;
public CarAdapter1(Context context, List<CartBean.DataBean> list) {
this.context = context;
this.mList = list;
from = LayoutInflater.from(context);
}
@NonNull
@Override
public CarAdapter1.CarHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
final View inflate = from.inflate(R.layout.rec1, viewGroup, false);
final CarHolder carHolder = new CarHolder(inflate);
return carHolder;
}
@Override
public void onBindViewHolder(@NonNull CarAdapter1.CarHolder carHolder, final int i) {
carHolder.tv_shang.setText(mList.get(i).getSellerName());
final List<CartBean.DataBean.ListBean> list=mList.get(i).getList();
carHolder.rec1.setLayoutManager(new LinearLayoutManager(context));
CarAdapter2 carAdapter2=new CarAdapter2(context,mList.get(i).getList());
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(context);
carHolder.rec1.setAdapter(carAdapter2);
//复选框
carHolder.box_shang.setChecked(mList.get(i).isCheck());
carAdapter2.setListener(new CarAdapter2.ShopCallBackListener() {
@Override
public void callBack() {
//商品适配里回调给 Activity计算总数 总价格
if (mShopCallBackListener!=null){
mShopCallBackListener.callBack();
}
mList.get(i).getList();
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
public class CarHolder extends RecyclerView.ViewHolder {
private final TextView tv_shang;
private final CheckBox box_shang;
private final RecyclerView rec1;
public CarHolder(@NonNull View itemView) {
super(itemView);
tv_shang = itemView.findViewById(R.id.tv_shang);
box_shang = itemView.findViewById(R.id.shang_box);
rec1 = itemView.findViewById(R.id.pin_rec);
}
}
private CarAdapter2.ShopCallBackListener mShopCallBackListener;
public void setListener(ShopCallBackListener listener){
this.mShopCallBackListener= (CarAdapter2.ShopCallBackListener) listener;
}
public interface ShopCallBackListener{
void callBack(List<CartBean.DataBean> list);
}
}
回调给Activity
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<CartBean.DataBean> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=findViewById(R.id.shang_rec);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
ShopPresenter shopPresenter=new ShopPresenter(this);
shopPresenter.getModelData();
}
public void getViewData(Object data) {
CartBean cartBean= (CartBean) data;
list = cartBean.getData();
//适配器
CarAdapter1 adapter1=new CarAdapter1(MainActivity.this,list);
recyclerView.setAdapter(adapter1);
}
}
展示出商家
商品适配器
public class CarAdapter2 extends RecyclerView.Adapter<CarAdapter2.CarHolder1> {
private Context context;
private List<CartBean.DataBean.ListBean> mList;
private final LayoutInflater from;
private CarHolder1 carHolder1;
public CarAdapter2(Context context, List<CartBean.DataBean.ListBean> mList) {
this.context=context;
this.mList=mList;
from = LayoutInflater.from(context);
}
@NonNull
@Override
public CarAdapter2.CarHolder1 onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view=from.inflate(R.layout.rec2,viewGroup,false);
carHolder1 = new CarHolder1(view);
return carHolder1;
}
@Override
public void onBindViewHolder(@NonNull CarAdapter2.CarHolder1 carHolder1, final int i) {
carHolder1.tv_neirong.setText(mList.get(i).getTitle());
carHolder1.tv_shang_price.setText(mList.get(i).getPrice()+"元");
Glide.with(context).load(mList.get(i).getImages().split("\\|")[0].replace("https","http")).into(carHolder1.image_pin);
//设置自定义View
carHolder1.customAddView.setData(this,mList,i);
carHolder1.customAddView.setOnCallBack(new CustomAddView.CallBackListener() {
@Override
public void callBack() {
if (mShopCallBackListener!=null){
mShopCallBackListener.callBack();
}
}
});
carHolder1.box_pin.setChecked(mList.get(i).isCheck);
carHolder1.box_pin.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mList.get(i).setCheck(isChecked);
//回调,目的是告诉activity有人改变状态
if (mShopCallBackListener!=null){
mShopCallBackListener.callBack();
}
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
public class CarHolder1 extends RecyclerView.ViewHolder {
private final TextView tv_neirong;
private final ImageView image_pin;
private final CheckBox box_pin;
private final RecyclerView rec_pin;
private final CustomAddView customAddView;
private final TextView tv_shang_price;
public CarHolder1(@NonNull View itemView) {
super(itemView);
tv_neirong = itemView.findViewById(R.id.neirong);
image_pin = itemView.findViewById(R.id.image_pin);
box_pin = itemView.findViewById(R.id.pin_box);
rec_pin = itemView.findViewById(R.id.pin_rec);
customAddView = itemView.findViewById(R.id.custom_product);
tv_shang_price=itemView.findViewById(R.id.tv_shang_price);
}
}
private ShopCallBackListener mShopCallBackListener;
public void setListener(ShopCallBackListener listener) {
this.mShopCallBackListener = listener;
}
public interface ShopCallBackListener {
void callBack();
}
}
传给子条目
public class CustomAddView extends RelativeLayout implements View.OnClickListener {
Context mContext;
private EditText mEditCar;
private List<CartBean.DataBean.ListBean> listBeans;
private CarAdapter2 carAdapter2;
private int i;
public CustomAddView(Context context) {
super(context);
init(context);
}
public CustomAddView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomAddView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
this.mContext = context;
View view = View.inflate(context, R.layout.car_num, null);
ImageView addIamge = (ImageView) view.findViewById(R.id.add_car);
ImageView jianIamge = (ImageView) view.findViewById(R.id.jian_car);
mEditCar = view.findViewById(R.id.edit_shop_car);
addIamge.setOnClickListener(this);
jianIamge.setOnClickListener(this);
addView(view);
mEditCar.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) {
num = Integer.parseInt(s.toString());
//TODO:改变数量
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private int num;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.add_car:
//改变数量,设置数量,改变对象内容,回调,局部刷新
num++;
mEditCar.setText(num + "");
listBeans.get(i).getNum();
break;
case R.id.jian_car:
if (num > 1) {
num--;
mEditCar.setText(num + "");
} else {
Toast.makeText(mContext, "商品数量不能小于1", Toast.LENGTH_LONG).show();
}
// mEditCar.setText(num + “”);
listBeans.get(position).setNum(num);
mCallBackListener.callBack();
// mProductsAdapter.notifyItemChanged(position);
break;
default:
break;
}
}
public void setData(CarAdapter2 carAdapter2, List<CartBean.DataBean.ListBean> list, int position) {
this.listBeans = list;
this.carAdapter2 = carAdapter2;
i = position;
num = Integer.parseInt(listBeans.get(i).getNum());
mEditCar.setText(this.num + “”);
}
private CallBackListener mCallBackListener;
public void setOnCallBack(CallBackListener listener) {
this.mCallBackListener = listener;
}
public interface CallBackListener {
void callBack();
}
}
以上是实现的代码
这是布局
布局分别是RecycView嵌套
MianActivity布局
<android.support.v7.widget.RecyclerView
android:id="@+id/shang_rec"
android:layout_width=“match_parent”
android:layout_height=“match_parent”></android.support.v7.widget.RecyclerView>
<RelativeLayout
android:id="@+id/layout_buttom"
android:layout_width="match_parent"
android:background="#ffffff"
android:layout_height="0dp"
android:layout_weight="1"
>
<CheckBox
android:id="@+id/quan_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="全选/全不选" />
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/quan_box"
android:layout_alignParentStart="true"
android:layout_marginStart="118dp"
android:layout_marginBottom="-16dp"
android:text="合计: 0.00"
android:textSize="16sp" />
<RelativeLayout
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_marginTop="0dp"
android:background="#FF0000">
<TextView
android:id="@+id/sum_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_alignParentEnd="true"
android:layout_marginEnd="25dp"
android:layout_marginBottom="0dp"
android:text=" 去结算 (0)" />
</RelativeLayout>
</RelativeLayout>
RecyclerView1
<?xml version="1.0" encoding="utf-8"?><LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="40dp">
<CheckBox
android:id="@+id/shang_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tv_shang"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="商家"
/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/pin_rec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView>
RecyclerView2
<?xml version="1.0" encoding="utf-8"?><CheckBox
android:id="@+id/pin_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/image_pin"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_launcher_background"
/>
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="80dp">
<TextView
android:id="@+id/neirong"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内容"
/>
<RelativeLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:id="@+id/tv_shang_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="商品价格" />
<com.example.wo.shopcar.mvp.view.CustomAddView
android:id="@+id/custom_product"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_shang_price"
android:layout_alignParentStart="true"
android:layout_marginStart="76dp"
android:layout_marginTop="-6dp"></com.example.wo.shopcar.mvp.view.CustomAddView>
</RelativeLayout>
</RelativeLayout>
<View
android:background="#cccccc"
android:layout_width="match_parent"
android:layout_height="5dp"/>
加减器
<?xml version="1.0" encoding="utf-8"?><ImageView
android:id="@+id/jian_car"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:src="@mipmap/jian" />
<ImageView
android:id="@+id/add_car"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/edit_shop_car"
android:src="@mipmap/add" />
<EditText
android:id="@+id/edit_shop_car"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/jian_car"
android:background="@drawable/home_shop_bg"
android:gravity="center_horizontal"
android:inputType="number"
android:text="1"
android:textSize="14sp" />