Android(安卓)- 购物车页面【仿】淘宝App
16lz
2022-04-18
首先是效果图
xml布局文件
activity_shopping.xml
"http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> id="@+id/re" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true"> id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="〈" android:textSize="20dp" /> id="@+id/shop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="购物车(0)" android:textSize="20dp" /> id="@+id/bj" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginTop="14dp" android:text="编辑" android:textSize="20dp" /> id="@+id/re2" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true"> id="@+id/all" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全选" /> id="@+id/price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/all" android:layout_centerHorizontal="true" android:text="总价:0.00" /> id="@+id/expandablelistview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/re2" android:layout_below="@id/re">
add_delete.xml
"http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-" android:textSize="20dp" /> id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="0" android:textSize="20dp" /> id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="+" android:textSize="20dp" />
child_item.xml
"http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> "@+id/main_check_all" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/textView4" /> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/imageView3" android:layout_width="90dp" android:layout_height="90dp" android:layout_alignParentTop="true" android:layout_toEndOf="@+id/main_check_all" android:layout_toRightOf="@+id/main_check_all" /> "@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toEndOf="@+id/imageView3" android:layout_toRightOf="@+id/imageView3" android:text="TextView" android:textSize="15dp" /> "@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/main_check_all" android:layout_toEndOf="@+id/imageView3" android:layout_toRightOf="@+id/imageView3" android:text="TextView" android:textColor="#c91622" android:textSize="10dp" /> <com.bwei.view.ShopAddDelete android:id="@+id/ad" android:layout_width="80dp" android:layout_height="30dp" android:layout_alignBottom="@+id/imageView3" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" />
group_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:paddingLeft="20sp" android:layout_height="match_parent"> <CheckBox android:id="@+id/main_check_all" android:layout_width="35dp" android:layout_height="35dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/main_check_all" android:layout_alignBottom="@+id/main_check_all" android:layout_toEndOf="@+id/main_check_all" android:layout_toRightOf="@+id/main_check_all" android:text="TextView" />RelativeLayout>
java文件
adapter文件夹:适配器
ExpandAdapter.java
public class ExpandAdapter extends BaseExpandableListAdapter implements IView { private Context context; private List data1; private List> data2; public static int q = 0; public ExpandAdapter(Context context, List data1, List> data2) { this.context = context; this.data1 = data1; this.data2 = data2; } @Override public int getGroupCount() { return data1.size(); } @Override public int getChildrenCount(int i) { return data2.get(i).size(); } @Override public Object getGroup(int i) { return data1.get(i); } @Override public Object getChild(int i, int i1) { return data2.get(i).get(i1); } @Override public long getGroupId(int i) { return i; } @Override public long getChildId(int i, int i1) { return i1; } @Override public boolean hasStableIds() { return false; } @Override public void onSuccess(Object o) { DeBean d = (DeBean) o; Toast.makeText(context, d.getMsg(), Toast.LENGTH_SHORT).show(); data1.clear(); data2.clear(); ShoppingActivity s = (ShoppingActivity) context; s.se(); } @Override public void onFailed(Exception e) { } class ViewHolder { CheckBox check; TextView tv; } class ViewHolder2 { CheckBox check; ImageView image; TextView tv1, tv2; ShopAddDelete ad; Button b; } @Override public View getGroupView(final int i, final boolean b, View view, ViewGroup viewGroup) { final ViewHolder holder; if (view == null) { holder = new ViewHolder(); view = View.inflate(context, R.layout.group_item, null); holder.check = view.findViewById(R.id.main_check_all); holder.tv = view.findViewById(R.id.textView3); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } holder.tv.setText(data1.get(i).getName()); holder.check.setChecked(data1.get(i).isFlag()); holder.check.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ShoppingActivity s = (ShoppingActivity) context; //Group布尔值变成选中状态 data1.get(i).setFlag(holder.check.isChecked()); //遍历Group集合 for (int i = 0; i < data1.size(); i++) { //如果有一个未选中 全选变成false并跳出 if (!data1.get(i).isFlag()) { s.all.setChecked(false); break; } else {//全部选中 全选变成true s.all.setChecked(true); } } //Child集合布尔值为选中的状态 for (int j = 0; j < data2.get(i).size(); j++) { data2.get(i).get(j).setFlag(holder.check.isChecked()); } //刷新适配器 notifyDataSetChanged(); //调用计算的方法 s.js(); } }); return view; } @Override public View getChildView(final int i, final int i1, final boolean b, View view, ViewGroup viewGroup) { final ViewHolder2 holder2; if (view == null) { holder2 = new ViewHolder2(); view = View.inflate(context, R.layout.child_item, null); holder2.check = view.findViewById(R.id.main_check_all); holder2.image = view.findViewById(R.id.imageView3); holder2.tv1 = view.findViewById(R.id.textView4); holder2.tv2 = view.findViewById(R.id.textView5); holder2.ad = view.findViewById(R.id.ad); holder2.b = view.findViewById(R.id.button2); view.setTag(holder2); } else { holder2 = (ViewHolder2) view.getTag(); } String images = data2.get(i).get(i1).getImage(); String[] split = images.split("!"); holder2.image.setImageURI(Uri.parse(split[0])); holder2.tv1.setText(data2.get(i).get(i1).getTitle()); holder2.tv2.setText(data2.get(i).get(i1).getPrice() + ""); holder2.ad.count.setText(data2.get(i).get(i1).getNum() + ""); holder2.check.setChecked(data2.get(i).get(i1).isFlag()); if (q == 0) { holder2.b.setVisibility(View.GONE); } else { holder2.b.setVisibility(View.VISIBLE); } holder2.b.setOnClickListener(new View.OnClickListener() { private DePresenter dePresenter; @Override public void onClick(View view) { //http://120.27.23.105/product/deleteCart?source=android&uid=1653&pid=2 dePresenter = new DePresenter(ExpandAdapter.this); Map map = new HashMap<>(); map.put("source", "android"); map.put("uid", "1653"); map.put("pid", data2.get(i).get(i1).getPid() + ""); dePresenter.get("http://120.27.23.105/", map); } }); holder2.check.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ShoppingActivity s = (ShoppingActivity) context; //Child布尔值变成选中状态 data2.get(i).get(i1).setFlag(holder2.check.isChecked()); //遍历Ghild集合 for (int i = 0; i < data2.size(); i++) { for (int j = 0; j < data2.get(i).size(); j++) { //如果有一个未选中 全选与商家按钮变成false并跳出 if (!data2.get(i).get(j).isFlag()) { data1.get(i).setFlag(false); s.all.setChecked(false); break; } else {//全部选中 全选与商家按钮变成true data1.get(i).setFlag(true); s.all.setChecked(true); } } } //二次遍历 for (int i = 0; i < data1.size(); i++) { boolean flag = data1.get(i).isFlag(); if (flag) { s.all.setChecked(true); } else { s.all.setChecked(false); break; } } notifyDataSetChanged(); //调用计算的方法 s.js(); } }); holder2.ad.setOnAddDeleteClick(new ShopAddDelete.OnAddDeleteClickListener() { @Override public void onAddClick(View v) { ShoppingActivity s = (ShoppingActivity) context; int number = holder2.ad.getNumber(); number++; holder2.ad.setNumber(number); Log.i("TAG", number + ""); data2.get(i).get(i1).setNum(number); notifyDataSetChanged(); //调用计算的方法 s.js(); } @Override public void onDelClick(View v) { ShoppingActivity s = (ShoppingActivity) context; int number = holder2.ad.getNumber(); number--; if (number > 0) { holder2.ad.setNumber(number); data2.get(i).get(i1).setNum(number); } else { Toast.makeText(context, "最小数量为1", Toast.LENGTH_SHORT).show(); } notifyDataSetChanged(); //调用计算的方法 s.js(); } }); return view; } @Override public boolean isChildSelectable(int i, int i1) { return false; }
app文件夹:图片加载
App.java
public class App extends Application { @Override public void onCreate() { super.onCreate(); Fresco.initialize(this); }}
bean文件夹:数据解析
Child.java
private boolean flag; private String image; private String title; private double price; private int num; private int pid; public Child(boolean flag, String image, String title, double price, int num, int pid) { this.flag = flag; this.image = image; this.title = title; this.price = price; this.num = num; this.pid = pid; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getNum() { return num; } public void setNum(int num) { this.num = num; }}
DeBean.java
private String msg; private String code; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; }}
Group.java
private boolean flag; private String name; public Group(boolean flag, String name) { this.flag = flag; this.name = name; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
SeBean.java
private String msg; private String code; private List data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public List getData() { return data; } public void setData(List data) { this.data = data; } public static class DataBean { private String sellerName; private String sellerid; private List list; public String getSellerName() { return sellerName; } public void setSellerName(String sellerName) { this.sellerName = sellerName; } public String getSellerid() { return sellerid; } public void setSellerid(String sellerid) { this.sellerid = sellerid; } public List getList() { return list; } public void setList(List list) { this.list = list; } public static class ListBean { private double bargainPrice; private String createtime; private String detailUrl; private String images; private int num; private int pid; private double price; private int pscid; private int selected; private int sellerid; private String subhead; private String title; public double getBargainPrice() { return bargainPrice; } public void setBargainPrice(double bargainPrice) { this.bargainPrice = bargainPrice; } public String getCreatetime() { return createtime; } public void setCreatetime(String createtime) { this.createtime = createtime; } public String getDetailUrl() { return detailUrl; } public void setDetailUrl(String detailUrl) { this.detailUrl = detailUrl; } public String getImages() { return images; } public void setImages(String images) { this.images = images; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getPscid() { return pscid; } public void setPscid(int pscid) { this.pscid = pscid; } public int getSelected() { return selected; } public void setSelected(int selected) { this.selected = selected; } public int getSellerid() { return sellerid; } public void setSellerid(int sellerid) { this.sellerid = sellerid; } public String getSubhead() { return subhead; } public void setSubhead(String subhead) { this.subhead = subhead; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } }}
model文件夹:数据层
DeModel.java
public class DeModel implements IModel { private DePresenter presenter; public DeModel(DePresenter presenter) { this.presenter = presenter; } @Override public void get(String baseurl, Map map) { Flowable flowable = RetrofitUtils.getInstance(baseurl).getretrofit().create(ApiService.class).deget(map); presenter.getData(flowable); }}
IModel.java
public interface IModel { void get(String baseurl, Map map);}
SeModel。java
public class SeModel implements IModel { private SePresenter presenter; public SeModel(SePresenter presenter) { this.presenter = presenter; } @Override public void get(String baseurl, Map map) { Flowable flowable = RetrofitUtils.getInstance(baseurl).getretrofit().create(ApiService.class).seget(map); presenter.getData(flowable); }}
net文件夹:网络请求
ApiService.java
//http://120.27.23.105/product/getCarts?source=android&uid=1653 @GET("product/getCarts") Flowable<SeBean> seget(@QueryMap Map<String, String> map); //http://120.27.23.105/product/deleteCart?source=android&uid=1653&pid=2 @GET("product/deleteCart") Flowable<DeBean> deget(@QueryMap Map<String, String> map);
RetrofitUtils.java
public class RetrofitUtils { private static volatile RetrofitUtils instance; private final Retrofit retrofit; private RetrofitUtils(String baseurl) { retrofit = new Retrofit.Builder() .baseUrl(baseurl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static RetrofitUtils getInstance(String baseurl) { if (instance == null) { synchronized (RetrofitUtils.class) { if (instance == null) { instance = new RetrofitUtils(baseurl); } } } return instance; } public Retrofit getretrofit() { return retrofit; }}
presenter文件夹:逻辑层
BasePresenter.java
public interface BasePresenter { void get(String baseurl, Map<String, String> map); void get2(String baseurl, Map<String, String> map);}
DePresenter.java
public class DePresenter implements BasePresenter { private IView iv; private DisposableSubscriber disposableSubscriber; public DePresenter(IView iv) { this.iv = iv; } @Override public void get(String baseurl, Map map) { DeModel model = new DeModel(this); model.get(baseurl, map); } @Override public void get2(String baseurl, Map map) { } public void getData(Flowable flowable) { disposableSubscriber = flowable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSubscriber() { @Override public void onNext(DeBean deBean) { iv.onSuccess(deBean); } @Override public void onError(Throwable t) { iv.onFailed((Exception) t); } @Override public void onComplete() { } }); } //防止内存泄漏 public void detatch() { if (iv != null) { iv = null; } if (disposableSubscriber != null) { if (!disposableSubscriber.isDisposed()) { disposableSubscriber.dispose(); } } }}
SePresenter.java
public class SePresenter implements BasePresenter { private IView iv; private DisposableSubscriber disposableSubscriber; public SePresenter(IView iv) { this.iv = iv; } @Override public void get(String baseurl, Map map) { SeModel model = new SeModel(this); model.get(baseurl, map); } @Override public void get2(String baseurl, Map map) { } public void getData(Flowable flowable) { disposableSubscriber = flowable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSubscriber() { @Override public void onNext(SeBean seBean) { iv.onSuccess(seBean); } @Override public void onError(Throwable t) { iv.onFailed((Exception) t); } @Override public void onComplete() { } }); } //防止内存泄漏 public void detatch() { if (iv != null) { iv = null; } if (disposableSubscriber != null) { if (!disposableSubscriber.isDisposed()) { disposableSubscriber.dispose(); } } }
view文件夹:视图层
IView.java
public interface IView { void onSuccess(Object o); void onFailed(Exception e);}
ShopAddDelete.java
public class ShopAddDelete extends RelativeLayout { public TextView count; public ShopAddDelete(Context context) { this(context, null); } public ShopAddDelete(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ShopAddDelete(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context, attrs, defStyleAttr); } private OnAddDeleteClickListener listener; //对外提供一个点击的回调接口 public interface OnAddDeleteClickListener { void onAddClick(View v); void onDelClick(View v); } public void setOnAddDeleteClick(OnAddDeleteClickListener listener) { this.listener = listener; } private void initView(final Context context, AttributeSet attrs, int defStyleAttr) { View view = View.inflate(context, R.layout.add_delete, this); TextView delete = (TextView) view.findViewById(R.id.delete); count = (TextView) view.findViewById(R.id.count); TextView add = (TextView) view.findViewById(R.id.add); delete.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { listener.onDelClick(view); } }); add.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { listener.onAddClick(view); } }); } //对外提供设置EditText值的方法 public void setNumber(int number) { count.setText(number + ""); } //得到控件原来的值,并转成int类型 public int getNumber() { int number = Integer.parseInt(count.getText().toString().trim()); return number; }
ShoppingActivity.java
public class ShoppingActivity extends AppCompatActivity implements IView { @BindView(R.id.back) TextView back; @BindView(R.id.shop) TextView shop; @BindView(R.id.re) RelativeLayout re; @BindView(R.id.bj) TextView bj; @BindView(R.id.price) TextView price; @BindView(R.id.button) Button button; @BindView(R.id.re2) RelativeLayout re2; @BindView(R.id.expandablelistview) ExpandableListView expandablelistview; private SePresenter sePresenter; private List grouplist = new ArrayList<>(); private List> childlist = new ArrayList<>(); public static CheckBox all; private ExpandAdapter expandAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shopping); all = (CheckBox) findViewById(R.id.all); ButterKnife.bind(this); all.setChecked(true); expandAdapter = new ExpandAdapter(this, grouplist, childlist); expandablelistview.setAdapter(expandAdapter); //http://120.27.23.105/product/getCarts?source=android&uid=1653 se(); bj.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (bj.getText().toString().trim().equals("编辑")) { ExpandAdapter.q = 1; expandAdapter.notifyDataSetChanged(); bj.setText("完成"); } else { ExpandAdapter.q = 0; expandAdapter.notifyDataSetChanged(); bj.setText("编辑"); } } }); } public void se() { sePresenter = new SePresenter(this); Map map = new HashMap<>(); map.put("source", "android"); map.put("uid", "1653"); sePresenter.get("http://120.27.23.105/", map); } @OnClick({R.id.back, R.id.all}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.back: finish(); break; case R.id.all: for (int i = 0; i < grouplist.size(); i++) { grouplist.get(i).setFlag(all.isChecked()); } for (int i = 0; i < childlist.size(); i++) { for (int j = 0; j < childlist.get(i).size(); j++) { childlist.get(i).get(j).setFlag(all.isChecked()); } } js(); expandAdapter.notifyDataSetChanged(); break; } } @Override public void onSuccess(Object o) { SeBean s = (SeBean) o; List data2 = s.getData(); for (int i = 0; i < data2.size(); i++) { grouplist.add(new Group(true, data2.get(i).getSellerName())); List list = data2.get(i).getList(); List cl = new ArrayList<>(); for (int j = 0; j < list.size(); j++) { cl.add(new Child(true, list.get(j).getImages(), list.get(j).getTitle(), list.get(j).getPrice(), list.get(j).getNum(), list.get(j).getPid())); } childlist.add(cl); } for (int q = 0; q < expandAdapter.getGroupCount(); q++) { expandablelistview.expandGroup(q); } expandAdapter.notifyDataSetChanged(); } @Override public void onFailed(Exception e) { } public void js() { double p = 0; int s = 0; for (int i = 0; i < childlist.size(); i++) { for (int j = 0; j < childlist.get(i).size(); j++) { if (childlist.get(i).get(j).isFlag()) { double price = childlist.get(i).get(j).getPrice(); int num = childlist.get(i).get(j).getNum(); p += price * num; s++; } } } DecimalFormat df = new DecimalFormat("######0.00"); price.setText("总价:" + df.format(p)); button.setText("去支付(" + s + ")"); shop.setText("购物车(" + s + ")"); }}
更多相关文章
- android 中 CheckBox 复选框操作
- Android(安卓)把Layout变成图片
- Eclipse搭建Android开发环境
- as随笔
- Android(安卓)图标设置 尺寸
- android 城市列表
- eclipse上Android(安卓)NDK开发环境搭建
- Android(安卓)7.0 自动安装APK及拍照崩溃问题
- Android分辨率自适应