购物车逻辑
效果图
1.MainActivity
public class MainActivity extends BaseActivity implements View.OnClickListener {
private Button mShouBtn;
private Button mDingBtn;
private Button mWoBtn;
private FragmentManager manager;
private AFragment aFragment;
private BFragment bFragment;
private CFragment cFragment;
@Override
protected int getLayout() {
return R.layout.activity_main;
}
@Override
protected void initView() {
mShouBtn = findViewById(R.id.Btn_ShouYe);
mDingBtn = findViewById(R.id.Btn_DingDan);
mWoBtn = findViewById(R.id.Btn_WoDe);
manager = getSupportFragmentManager();
//初始化
aFragment = new AFragment();
bFragment = new BFragment();
cFragment = new CFragment();
}
@Override
protected void setOnclick() {
mShouBtn.setOnClickListener(this);
mDingBtn.setOnClickListener(this);
mWoBtn.setOnClickListener(this);
}
@Override
protected void pageLogic() {
manager.beginTransaction().replace(R.id.Fram_Lay,aFragment).commit();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.Btn_ShouYe:
manager.beginTransaction().replace(R.id.Fram_Lay,aFragment).commit();
break;
case R.id.Btn_DingDan:
manager.beginTransaction().replace(R.id.Fram_Lay,bFragment).commit();
break;
case R.id.Btn_WoDe:
manager.beginTransaction().replace(R.id.Fram_Lay,cFragment).commit();
break;
}
}
}
主布局
<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">
<LinearLayout
android:id="@+id/Lay_Out"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<Button
android:id="@+id/Btn_ShouYe"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="首页" />
<Button
android:id="@+id/Btn_DingDan"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="订单" />
<Button
android:id="@+id/Btn_WoDe"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="我的" />
</LinearLayout>
<FrameLayout
android:id="@+id/Fram_Lay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/Lay_Out"></FrameLayout>
/RelativeLayout>
自己添加两个boolean类型 用来判断是否选中
2.BFragment
public class BFragment extends Fragment implements IVIew {
private CheckBox Check_All;
private TextView All_Price;
private TextView Go_To_JS;
private String mUrl = "http://www.wanandroid.com/tools/mockapi/6523/restaurant-list";
private ArrayList<MyData.DataBean> mList = new ArrayList<>();
private ExpandableListView mExpandView;
private GWAdapter mAdapter;
private PresenterImpl presenter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_b, null);
initView(view);
pageLogic();
return view;
}
private void pageLogic() {
presenter = new PresenterImpl(this);
presenter.startRequest(mUrl, null);
}
private void initView(View view) {
Check_All = view.findViewById(R.id.Check_All);
All_Price = view.findViewById(R.id.All_Price);
Go_To_JS = view.findViewById(R.id.Go_To_JS);
mExpandView = view.findViewById(R.id.Expand_View);
mAdapter = new GWAdapter(mList, getContext());
mExpandView.setAdapter(mAdapter);
//去掉自带的小箭头
mExpandView.setGroupIndicator(null);
mAdapter.setCallBack(new GWAdapter.AdapterCallback() {
@Override
public void setGroupCheck(int groupPosition) {
//是否被全选中
boolean childAllCheck = mAdapter.isChildAllCheck(groupPosition);
mAdapter.childAllCheck(groupPosition, !childAllCheck);
mAdapter.notifyDataSetChanged();
flushBottomLayout();
}
@Override
public void setChildCheck(int groupPosition, int childPosition) {
//得到你要点击的商品Child是否是选中状态
boolean childChecked = mAdapter.isChildChecked(groupPosition, childPosition);
mAdapter.setChildChecked(groupPosition, childPosition, !childChecked);
mAdapter.notifyDataSetChanged();
flushBottomLayout();
}
@Override
public void setNumber(int groupPosition, int childPosition, int number) {
mAdapter.setShangPinNumber(groupPosition, childPosition, number);
mAdapter.notifyDataSetChanged();
flushBottomLayout();
}
});
//底部全选监听事件
Check_All.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean allGoods = mAdapter.isAllGoods();
mAdapter.setAllGoodsIsChecked(!allGoods);
mAdapter.notifyDataSetChanged();
flushBottomLayout();
}
});
}
@Override
public void success(Object data) {
MyData myData = (MyData) data;
mList.addAll(myData.getData());
mAdapter.notifyDataSetChanged();
//首次加载全展开
for (int i = 0; i <mList.size() ; i++) {
mExpandView.expandGroup(i);
}
//不能伸缩
mExpandView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
return true;
}
});
}
@Override
public void error(Object error) {
}
private void flushBottomLayout() {
//刷新全选
boolean allGoods = mAdapter.isAllGoods();
Check_All.setChecked(allGoods);
float allGoodPrice = mAdapter.getAllGoodPrice();
int allGoodNumber = mAdapter.getAllGoodNumber();
All_Price.setText("价格:"+allGoodPrice);
Go_To_JS.setText("去结算("+allGoodNumber+")");
}
@Override
public void onStop() {
super.onStop();
mList.clear();
}
}
3.BFargment布局
<RelativeLayout
android:id="@+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<CheckBox
android:id="@+id/Check_All"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选" />
<TextView
android:id="@+id/All_Price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="价格" />
<TextView
android:id="@+id/Go_To_JS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="去结算(0)" />
</RelativeLayout>
<ExpandableListView
android:id="@+id/Expand_View"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_layout" />
4.适配器
public class GWAdapter extends BaseExpandableListAdapter {
private ArrayList<MyData.DataBean> mList;
private Context mContext;
public GWAdapter(ArrayList<MyData.DataBean> mList, Context mContext) {
this.mList = mList;
this.mContext = mContext;
}
@Override
public int getGroupCount() {
return mList.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return mList.get(groupPosition).getSpus().size();
}
@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 View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder holder = null;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.group_item, null);
holder = new GroupHolder();
holder.mGroupCheck = convertView.findViewById(R.id.Group_Check);
holder.mGroupTv = convertView.findViewById(R.id.Group_Name);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
holder.mGroupTv.setText(mList.get(groupPosition).getName() + "");
//自动选中 当子条目全部选中 小组的checkbox自动会被选中
boolean childAllCheck = isChildAllCheck(groupPosition);
holder.mGroupCheck.setChecked(childAllCheck);
//点击事件
holder.mGroupCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapterCallback != null) {
adapterCallback.setGroupCheck(groupPosition);
}
}
});
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder cholder = null;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.childe_item, null);
cholder = new ChildHolder();
cholder.mChildCheck = convertView.findViewById(R.id.Child_Check);
cholder.mChildTitle = convertView.findViewById(R.id.Child_title);
cholder.mChildPrice = convertView.findViewById(R.id.Child_price);
cholder.mImage = convertView.findViewById(R.id.Child_Icon);
cholder.jiaJianView = convertView.findViewById(R.id.jia_jian_view);
convertView.setTag(cholder);
} else {
cholder = (ChildHolder) convertView.getTag();
}
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
Glide.with(mContext).load(spusBean.getPic_url()).into(cholder.mImage);
cholder.mChildPrice.setText(spusBean.getSkus().get(0).getPrice());
cholder.mChildTitle.setText(spusBean.getName() + "");
//子checkbox
cholder.mChildCheck.setChecked(spusBean.isChildChecked());
//通过方法赋值
cholder.jiaJianView.setNumber(spusBean.getPraise_num());
cholder.mChildCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (adapterCallback != null) {
adapterCallback.setChildCheck(groupPosition, childPosition);
}
}
});
//加减
cholder.jiaJianView.setOnChange(new JiaJianView.OnCountChange() {
@Override
public void setCount(int count) {
if (adapterCallback != null) {
adapterCallback.setNumber(groupPosition, childPosition, count);
}
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
class GroupHolder {
private CheckBox mGroupCheck;
private TextView mGroupTv;
}
class ChildHolder {
private CheckBox mChildCheck;
private TextView mChildTitle;
private ImageView mImage;
private TextView mChildPrice;
private JiaJianView jiaJianView;
}
//1.点击group的checkbox让child的全选中 只有全选 全不选功能
public void childAllCheck(int groupPosition, boolean isCheck) {
MyData.DataBean dataBean = mList.get(groupPosition);
List<MyData.DataBean.SpusBean> spus = dataBean.getSpus();
for (int i = 0; i < spus.size(); i++) {
MyData.DataBean.SpusBean spusBean = spus.get(i);
spusBean.setChildChecked(isCheck);
}
}
//3.判断小组是否全部选中
public boolean isChildAllCheck(int groupPosition) {
boolean boo = true;
MyData.DataBean dataBean = mList.get(groupPosition);
List<MyData.DataBean.SpusBean> spus = dataBean.getSpus();
for (int i = 0; i < spus.size(); i++) {
MyData.DataBean.SpusBean spusBean = spus.get(i);
//只要有一个没选中 点击checkbox就是全选功能
if (!spusBean.isChildChecked()) {
return false;
}
}
return boo;
}
//4.点击child给他赋值
public void setChildChecked(int groupPosition, int childPosition, boolean isCheckBox) {
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
spusBean.setChildChecked(isCheckBox);
}
//5.查看当前商品是否被选中
public boolean isChildChecked(int groupPosition, int childPosition) {
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
if (spusBean.isChildChecked()) {
return true;
}
return false;
}
//6.给商品数量赋值
public void setShangPinNumber(int groupPosition, int childPosition, int number) {
MyData.DataBean.SpusBean spusBean = mList.get(groupPosition).getSpus().get(childPosition);
spusBean.setPraise_num(number);
}
//7.底部视图有一个全选按钮 得到所有条目的状态
public boolean isAllGoods() {
boolean boo = true;
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (!spusBean.isChildChecked()) {
boo = false;
}
}
}
return boo;
}
//8.全选反选功能
public void setAllGoodsIsChecked(boolean isAllCheck) {
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
spusBean.setChildChecked(isAllCheck);
}
}
}
//9.计算所有商品的价格
public float getAllGoodPrice() {
float allPrice = 0;
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (spusBean.isChildChecked()) {
allPrice += spusBean.getPraise_num() * Float.parseFloat(spusBean.getSkus().get(0).getPrice());
}
}
}
return allPrice;
}
//10.计算所有的商品数量
public int getAllGoodNumber() {
int allNumber = 0;
for (int i = 0; i < mList.size(); i++) {
MyData.DataBean dataBean = mList.get(i);
for (int j = 0; j < dataBean.getSpus().size(); j++) {
MyData.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
if (spusBean.isChildChecked()) {
allNumber += spusBean.getPraise_num();
}
}
}
return allNumber;
}
//2.接口回调 声明一个接口
public interface AdapterCallback {
//小组
void setGroupCheck(int groupPosition);
//子条目
void setChildCheck(int groupPosition, int childPosition);
//点击加减按钮刷新
void setNumber(int groupPosition, int childPosition, int number);
}
private AdapterCallback adapterCallback;
public void setCallBack(AdapterCallback madapterCallback) {
this.adapterCallback = madapterCallback;
}
}
5.group_item
6.child_item
7.自定义view 加减器
public class JiaJianView extends LinearLayout implements View.OnClickListener {
private TextView mAdd;
private TextView mDelete;
private TextView mNumber;
//商品数量
private int mCount;
public JiaJianView(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.add_remove_view_layout, this);
initView();
}
private void initView() {
mAdd = findViewById(R.id.add_tv);
mDelete = findViewById(R.id.delete_tv);
mNumber = findViewById(R.id.product_number_tv);
mAdd.setOnClickListener(this);
mDelete.setOnClickListener(this);
}
public void setNumber(int number) {
this.mCount = number;
mNumber.setText(number + "");
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.delete_tv:
if (mCount > 0) {
mCount--;
mNumber.setText(mCount + "");
if (mOnCountChange != null) {
mOnCountChange.setCount(mCount);
}
} else {
Toast.makeText(getContext(), "商品已售空", Toast.LENGTH_SHORT).show();
}
break;
case R.id.add_tv:
mCount++;
mNumber.setText(mCount + "");
if (mOnCountChange != null) {
mOnCountChange.setCount(mCount);
}
break;
}
}
//接口回调
public interface OnCountChange {
void setCount(int count);
}
private OnCountChange mOnCountChange;
public void setOnChange(OnCountChange onCountChange) {
this.mOnCountChange = onCountChange;
}
}
8.自定义布局
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:background="#99000000"
android:gravity="center_vertical"
android:padding="2dp">
<TextView
android:id="@+id/delete_tv"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="center"
android:text="-"
android:textSize="16sp" />
<TextView
android:id="@+id/product_number_tv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:background="#ffffff"
android:gravity="center"
android:text="1" />
<TextView
android:id="@+id/add_tv"
android:layout_width="10dp"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:background="#ffffff"
android:gravity="center"
android:text="+"
android:textSize="16sp" />
/LinearLayout>
9.OkUtils 导依赖 okhttp
public class OkUtils {
private OkHttpClient okHttpClient;
private OkUtils() {
okHttpClient = new OkHttpClient.Builder().build();
}
public static OkUtils getInstance() {
return OkHolder.okutils;
}
//私有静态方法
private static class OkHolder {
//实例化
private static final OkUtils okutils = new OkUtils();
}
public void getAsync(String url, Callback callback){
Request request=new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(callback);
}
}
10.model
public class ModelImpl implements Model{
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==0){
String str= (String) msg.obj;
Gson gson=new Gson();
MyData myData = gson.fromJson(str, MyData.class);
callback.setData(myData);
}
}
};
private MyCallback callback;
@Override
public void getData(String url, String params, MyCallback callback) {
this.callback=callback;
OkUtils.getInstance().getAsync(url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String string = response.body().string();
mHandler.sendMessage(mHandler.obtainMessage(0,string));
}
});
}
}