1.首先 导入依赖 权限
(1) /*retrofit网络请求*/
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
/*eventbus传值*/
implementation 'org.greenrobot:eventbus:3.0.0'
/*RxAndroid所依赖的库*/
implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.1.6'
/*fresco图片处理*/
implementation 'com.facebook.fresco:fresco:1.11.0'
(2)网络权限
<uses-permission android:name="android.permission.INTERNET"/>
(3)Fresco初始化(创建一个App继承Application,写出他的onCreate的方法,写下变一句话就行了)
Fresco.initialize(this);
(4)清单文件注册 name
2.自定义加减器
(1)布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="60dp"
android:layout_height="30dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="-"
android:gravity="center"
android:id="@+id/sub_tv"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1"
android:gravity="center"
android:background="#eae2e2"
android:id="@+id/product_number_tv"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="+"
android:gravity="center"
android:id="@+id/add_tv"
android:textSize="16sp"/>
</LinearLayout>
(2)主要代码:
public class MyAddSubView extends LinearLayout implements View.OnClickListener {
private int number = 1;
private TextView sub_tv;
private TextView product_number_tv;
private TextView add_tv;
public MyAddSubView(Context context) {
this(context, null);
}
public MyAddSubView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyAddSubView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
View view = inflate(context, R.layout.add_remove_view_layout, this);
sub_tv=view.findViewById(R.id.sub_tv);
product_number_tv=view.findViewById(R.id.product_number_tv);
add_tv=view.findViewById(R.id.add_tv);
sub_tv.setOnClickListener(this);
add_tv.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sub_tv:
if (number > 1) {
--number;
product_number_tv.setText(number + "");
if (onNumberChangeListener != null) {
onNumberChangeListener.onNumberChange(number);
}
} else {
Toast.makeText(getContext(), "不能再少了", Toast.LENGTH_SHORT).show();
}
break;
case R.id.add_tv:
++number;
product_number_tv.setText(number + "");
if (onNumberChangeListener != null) {
onNumberChangeListener.onNumberChange(number);
}
break;
}
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
product_number_tv.setText(number + "");
}
OnNumberChangeListener onNumberChangeListener;
public void setOnNumberChangeListener(OnNumberChangeListener onNumberChangeListener) {
this.onNumberChangeListener = onNumberChangeListener;
}
public interface OnNumberChangeListener {
void onNumberChange(int num);
}
}
3.MainActivity主页面
(1)主页面布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ExpandableListView
android:id="@+id/el_cart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="#eeeeee"
android:gravity="center_vertical">
<CheckBox
android:id="@+id/cb_cart_all_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选" />
<TextView
android:id="@+id/tv_cart_total_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="20dp"
android:text="合计:¥0.00" />
<Button
android:id="@+id/btn_cart_pay"
android:layout_width="100dp"
android:layout_height="match_parent"
android:text="去结算(0)" />
</LinearLayout>
</RelativeLayout>
(2)主页面代码:
public class MainActivity extends AppCompatActivity implements ShopView {
private ExpandableListView el_cart;
private CheckBox cb_cart_all_select;
private TextView tv_cart_total_price;
private Button btn_cart_pay;
private ShopAdapter mShopAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
if (!EventBus.getDefault().isRegistered(true)){
EventBus.getDefault().register(this);
}
}
private void initData() {
ShopPresenter shopPresenter = new ShopPresenter(this);
shopPresenter.success("71");
}
@Override
public void success(ShopBean shopBean) {
List<ShopBean.DataBean> data = shopBean.getData();
mShopAdapter = new ShopAdapter(data, MainActivity.this);
el_cart.setAdapter(mShopAdapter);
//展开二级列表
for (int i = 0; i < data.size(); i++) {
el_cart.expandGroup(i);
}
}
private void initView() {
el_cart = (ExpandableListView) findViewById(R.id.el_cart);
cb_cart_all_select = (CheckBox) findViewById(R.id.cb_cart_all_select);
tv_cart_total_price = (TextView) findViewById(R.id.tv_cart_total_price);
btn_cart_pay = (Button) findViewById(R.id.btn_cart_pay);
cb_cart_all_select.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取当前的条目状态
boolean allCheckbox = mShopAdapter.isAllCheckbox();
//给条目赋值
mShopAdapter.isAllCheckBox(!allCheckbox);
//刷新
mShopAdapter.notifyDataSetChanged();
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onMessageEvent(CountPrice countPrice){
//总价
tv_cart_total_price.setText(countPrice.getPrice()+"");
//数量
btn_cart_pay.setText("去结算("+countPrice.getCount()+")");
}
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onMessageEvent(MessageEvent messageEvent){
cb_cart_all_select.setChecked(messageEvent.isCheck());
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁EventBus
if (EventBus.getDefault().isRegistered(true)){
EventBus.getDefault().unregister(this);
}
}
}
4.二级列表适配器层
(1)适配器父布局:
<?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="60dp"
android:gravity="center_vertical">
<CheckBox
android:id="@+id/seller_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/seller_name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="MMM"/>
</LinearLayout>
(2)适配器子布局:
<?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="120dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical">
<CheckBox
android:id="@+id/child_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/product_icon_iv"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="20dp"
app:placeholderImage="@mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/product_title_name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="商品标题" />
<TextView
android:id="@+id/product_price_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="¥0.0" />
</LinearLayout>
<com.bawie.shopcart3.MyAddSubView
android:id="@+id/add_remove_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp" />
</LinearLayout>
(3)适配器代码:
public class ShopAdapter extends BaseExpandableListAdapter {
private List<ShopBean.DataBean> mList;
private Context mContext;
public ShopAdapter(List<ShopBean.DataBean> list, Context context) {
mList = list;
mContext = context;
}
@Override
public int getGroupCount() {
return mList.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return mList.get(groupPosition).getList().size();
}
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
final OneViewHolder oneViewHolder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.adapter_one, null);
oneViewHolder = new OneViewHolder(convertView);
convertView.setTag(oneViewHolder);
} else {
oneViewHolder = (OneViewHolder) convertView.getTag();
}
oneViewHolder.seller_name_tv.setText(mList.get(groupPosition).getSellerName());
//判断所有的子条目是否选中
boolean cildChange = isCildChange(groupPosition);
//如果子条目选中 商家选中
oneViewHolder.seller_cb.setChecked(cildChange);
oneViewHolder.seller_cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取当前的状态值
boolean checked = oneViewHolder.seller_cb.isChecked();
//调用控制子条目全选
isCheckChange(groupPosition,checked);
//计算总价和数量
EventBus.getDefault().post(jiSuan());
//刷新适配器
notifyDataSetChanged();
}
});
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final TwoViewHolder twoViewHolder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.adapter_two, null);
twoViewHolder = new TwoViewHolder(convertView);
convertView.setTag(twoViewHolder);
}else {
twoViewHolder = (TwoViewHolder) convertView.getTag();
}
List<ShopBean.DataBean.ListBean> list = mList.get(groupPosition).getList();
final ShopBean.DataBean.ListBean listBean = list.get(childPosition);
//头像
String images = listBean.getImages();
String[] split = images.split("!");
twoViewHolder.product_icon_iv.setImageURI(split[0]);
//标题
twoViewHolder.product_title_name_tv.setText(listBean.getTitle());
//价格
twoViewHolder.product_price_tv.setText("¥"+listBean.getPrice());
//设置加减器的数量
twoViewHolder.add_remove_view.setNumber(listBean.getNum());
//子条目的选中状态
twoViewHolder.child_cb.setChecked(listBean.getSelected() == 1);
//加减器的监听
twoViewHolder.add_remove_view.setOnNumberChangeListener(new MyAddSubView.OnNumberChangeListener() {
@Override
public void onNumberChange(int num) {
//设置加减器的值
numBer(groupPosition,childPosition,num);
EventBus.getDefault().post(jiSuan());
//更新适配器
notifyDataSetChanged();
}
});
twoViewHolder.child_cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取当前的状态值
boolean checked = twoViewHolder.child_cb.isChecked();
if (checked){
listBean.setSelected(1);
}else {
listBean.setSelected(0);
}
EventBus.getDefault().post(jiSuan());
notifyDataSetChanged();
}
});
return convertView;
}
/**
* 通过一级列表控制二级列表
*/
private void isCheckChange(int i,boolean flag){
ShopBean.DataBean dataBean = mList.get(i);
List<ShopBean.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
list.get(j).setSelected(flag?1:0);
}
}
/**
* 判断所有的复选框是否选中
*/
public boolean isAllCheckbox(){
for (int i = 0; i < mList.size(); i++) {
ShopBean.DataBean dataBean = mList.get(i);
List<ShopBean.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
if (list.get(j).getSelected() == 0){
//等于0 就是没选中
return false;
}
}
}
return true;
}
/**
* 判断所有的子条目是否选中
*/
public boolean isCildChange(int groupPosition){
ShopBean.DataBean dataBean = mList.get(groupPosition);
List<ShopBean.DataBean.ListBean> list = dataBean.getList();
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getSelected() == 0){
//等于0 就是没选中
return false;
}
}
return true;
}
/**
* 判断全选框是否选中
*/
public void isAllCheckBox(boolean flag){
for (int i = 0; i < mList.size(); i++) {
ShopBean.DataBean dataBean = mList.get(i);
List<ShopBean.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
list.get(j).setSelected(flag?1:0);
}
}
EventBus.getDefault().post(jiSuan());
}
/**
* 设置加减器的值
*/
public void numBer(int groupPosition,int childPosition,int num){
ShopBean.DataBean dataBean = mList.get(groupPosition);
List<ShopBean.DataBean.ListBean> list = dataBean.getList();
list.get(childPosition).setNum(num);
}
/**
* 判断全选框
*/
public void isQuanXuan(boolean flag){
MessageEvent messageEvent = new MessageEvent(flag);
EventBus.getDefault().post(messageEvent);
}
private CountPrice jiSuan() {
int price = 0;
int num = 0;
int s = 1;
for (int i = 0; i < mList.size(); i++) {
ShopBean.DataBean dataBean = mList.get(i);
List<ShopBean.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
ShopBean.DataBean.ListBean listBean = list.get(j);
//只要选中的
if (listBean.getSelected() == 1){
num += listBean.getNum();
price += listBean.getNum() * listBean.getPrice();
}else {
s = 0;
}
}
}
if (s == 0){
isQuanXuan(false);
}else {
isQuanXuan(true);
}
CountPrice countPrice = new CountPrice();
countPrice.setCount(num);
countPrice.setPrice(price);
return countPrice;
}
@Override
public Object getGroup(int groupPosition) {
return null;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
public static class OneViewHolder {
public View rootView;
public CheckBox seller_cb;
public TextView seller_name_tv;
public OneViewHolder(View rootView) {
this.rootView = rootView;
this.seller_cb = (CheckBox) rootView.findViewById(R.id.seller_cb);
this.seller_name_tv = (TextView) rootView.findViewById(R.id.seller_name_tv);
}
}
public static class TwoViewHolder {
public View rootView;
public CheckBox child_cb;
public SimpleDraweeView product_icon_iv;
public TextView product_title_name_tv;
public TextView product_price_tv;
public MyAddSubView add_remove_view;
public TwoViewHolder(View rootView) {
this.rootView = rootView;
this.child_cb = (CheckBox) rootView.findViewById(R.id.child_cb);
this.product_icon_iv = (SimpleDraweeView) rootView.findViewById(R.id.product_icon_iv);
this.product_title_name_tv = (TextView) rootView.findViewById(R.id.product_title_name_tv);
this.product_price_tv = (TextView) rootView.findViewById(R.id.product_price_tv);
this.add_remove_view = (MyAddSubView) rootView.findViewById(R.id.add_remove_view);
}
}
}
(5)适配器两个补助类:
①第一个MessageEvent :
public class MessageEvent {
private boolean check;
//有参 set和get方法
public MessageEvent(boolean check) {
this.check = check;
}
public boolean isCheck() {
return check;
}
public void setCheck(boolean check) {
this.check = check;
}
}
②第二个CountPrice :
public class CountPrice {
private int count;
private int price;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
5.工具类:
(1)retrofitUtils网络请求:
public class RetrofitUtils {
public static RetrofitService getInstance(){
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(3, TimeUnit.SECONDS)
.writeTimeout(3, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(Constance.URL)
.client(okHttpClient)
.build();
RetrofitService retrofitService = retrofit.create(RetrofitService.class);
return retrofitService;
}
}
(2)接口:
public class Constance {
public static final String URL = "http://www.zhaoapi.cn/";
}
(3)RetrofitService拼接器:
public interface RetrofitService {
@GET("product/getCarts")
Observable<ShopBean> getShop(@Query("uid") String uid);
}
(4)bean类接口
http://www.zhaoapi.cn/product/getCarts?uid=71
6.MVP
(1)M:
public class ShopModel {
public void success(Observer<ShopBean> observer,String uid){
RetrofitService instance = RetrofitUtils.getInstance();
instance.getShop(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
}
(2)View:
public interface ShopView {
void success(ShopBean shopBean);
}
(3)Presenter:
public class ShopPresenter {
private ShopModel mShopModel;
private ShopView mShopView;
public ShopPresenter(ShopView shopView) {
mShopView = shopView;
mShopModel = new ShopModel();
}
public void success(String uid){
mShopModel.success(new Observer<ShopBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(ShopBean shopBean) {
mShopView.success(shopBean);
}
},uid);
}
}
这就完成了我们的购物车!加油