仿京东购物车——
//xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/biaoti" android:id="@+id/lin"></include>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.example.adoptionofreplies.view.ExpanableView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/expand_view"
android:layout_marginTop="15px"
android:layout_below="@id/lin"
>
</com.example.adoptionofreplies.view.ExpanableView>
</ScrollView>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:textSize="20sp"
android:paddingTop="10dp"
android:background="#ffffff"
android:gravity="right"
android:text="全选:"
/>
<CheckBox
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:background="#ffffff"
android:id="@+id/check_quanxuan"
/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:textSize="20sp"
android:gravity="right"
android:paddingTop="10dp"
android:background="#ffffff"
android:text="总价:"
/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:id="@+id/zong"
android:paddingTop="16dp"
android:textSize="15sp"
android:background="#ffffff"
android:text="0"
/>
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:text="结算(0)"
android:background="#ffffff"
android:id="@+id/button_jiesuan"
/>
</LinearLayout>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:textSize="20sp"
android:paddingTop="10dp"
android:background="#ffffff"
android:gravity="right"
android:text="全选:"
/>
<CheckBox
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:background="#ffffff"
android:id="@+id/check_quanxuan"
/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:textSize="20sp"
android:gravity="right"
android:paddingTop="10dp"
android:background="#ffffff"
android:text="总价:"
/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:id="@+id/zong"
android:paddingTop="16dp"
android:textSize="15sp"
android:background="#ffffff"
android:text="0"
/>
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:text="结算(0)"
android:background="#ffffff"
android:id="@+id/button_jiesuan"
/>
</LinearLayout>
</RelativeLayout>
//页面文件
<?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="match_parent" android:orientation="horizontal"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.1" > <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:id="@+id/cb" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5" android:orientation="horizontal" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <com.facebook.drawee.view.SimpleDraweeView android:layout_width="80dp" android:layout_height="80dp" android:id="@+id/sim" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/name" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/price" android:textColor="#ff00" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.25" android:orientation="horizontal" > <Button android:layout_width="30dp" android:layout_marginTop="30dp" android:layout_height="wrap_content" android:text="-" android:id="@+id/jian" /> <TextView android:layout_width="30dp" android:layout_marginTop="30dp" android:textSize="20sp" android:layout_height="wrap_content" android:text="0" android:id="@+id/zong" /> <Button android:layout_width="30dp" android:layout_marginTop="30dp" android:layout_height="wrap_content" android:text="+" android:id="@+id/jia" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.15" android:orientation="horizontal" > <Button android:layout_width="30dp" android:layout_height="30dp" android:id="@+id/shan" android:background="@drawable/rublish" android:layout_marginLeft="10dp" android:layout_marginTop="30dp" /> </LinearLayout> </LinearLayout>
//我这里用的MVP就不一一介绍了 我直接显示Api retrofit的使用
//查询
@GET("getCarts")
Call<GoodsBean>doGet(@Query("uid") int uid,@Query("source") String source);
//最主要更新 运用到加、减、全选
@GET("updateCarts")Call<UpBean>update(@Query("uid") int uid, @QueryMap Map<String,String> params);
//删除
@GET("product/deleteCart")Call<DeleteBean> del(@Query("uid") String uid,@Query("pid") String pid);
//单例
public class HttpUtils {
public static HttpUtils instance;
private Retrofit retrofit;
private HttpUtils(String uri){
retrofit = new Retrofit.Builder()
.baseUrl(uri)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static HttpUtils getInstance(String uri){
if(instance==null){
synchronized (HttpUtils.class){
if(null==instance){
instance = new HttpUtils(uri);
}
}
}
return instance;
}
public ApiServers getApi(){
return retrofit.create(ApiServers.class);
}
}
//主界面内容
public class MainActivity extends AppCompatActivity implements LogView {
private Handler handler = new Handler(){
@Override public void handleMessage(Message msg) {
if (msg.what==0){
//价格和数量的Bean类 并且赋值
CountPriceBean countAndPrice = (CountPriceBean) msg.obj;
text_heji.setText("¥"+countAndPrice.getPriceString());
text_jiesuan.setText("结算("+countAndPrice.getCount()+")");
}
}
};
String uri="http://120.27.23.105/product/";
private ExpandableListView ex;
private ChaXunAdapter adapter;
private MyPresenterView myPresenterView;
private CheckBox check_quanxuan;
private TextView text_heji;
private TextView text_jiesuan;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ex = findViewById(R.id.expanded_view);
check_quanxuan = findViewById(R.id.check_quanxuan);
text_heji = findViewById(R.id.text_heji);
text_jiesuan = findViewById(R.id.text_jiesuan);
//这里调用的p城的方法 并且把网址回去
myPresenterView = new MyPresenter(this);
myPresenterView.setNet(uri);
//全选
check_quanxuan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.isAllCheckChild(check_quanxuan.isChecked());
}
});
}
//这里是Logview自己的方法
@Override
public void toBackView(List<GoodsBean.DataBean> data) {
if (data != null) {
//默认二级条目全选
for (int i=0;i<data.size();i++){
if (isChildCheck(i,data)){
data.get(i).setGroup_check(true);
}
}
//全选图片默认选中
check_quanxuan.setChecked(isAllChildCheck(data));
//适配器
adapter = new ChaXunAdapter(MainActivity.this, data,myPresenterView,handler);
ex.setAdapter(adapter);
adapter.notifyDataSetChanged();
for (int i = 0; i < data.size(); i++) {
//默认展开
ex.expandGroup(i);
}
//这里是适配器里面的总价方法
adapter.sendPriceAndCount();
} else {
Toast.makeText(MainActivity.this, "购物车空,请添加购物车", Toast.LENGTH_SHORT).show();
}
}
//全选图片默认选中
private boolean isAllChildCheck(List<GoodsBean.DataBean> data) {
for (int i=0;i<data.size();i++){
if(!data.get(i).isGroup_check()){
return false;
}
}
return true;
}
//默认二级条目全选
private boolean isChildCheck(int i, List<GoodsBean.DataBean> data) {
GoodsBean.DataBean dataBean = data.get(i);
for (int j=0;j<dataBean.getList().size();j++){
if (dataBean.getList().get(j).getSelected()==0){
return false;
}
}
return true;
}
}
//适配器
public class ChaXunAdapter extends BaseExpandableListAdapter {
Context context;
List<GoodsBean.DataBean> data;
private int childIndex;
private MyPresenterView myPresenterView;
private Handler handler;
private int allIndex;
//适配的参数
public ChaXunAdapter(Context context, List<GoodsBean.DataBean> data, MyPresenterView myPresenterView, Handler handler) {
this.context=context;
this.data=data;
this.myPresenterView = myPresenterView;
this.handler = handler;
}
@Override
public int getGroupCount() {
return data.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return data.get(groupPosition).getList().size();
}
@Override
public Object getGroup(int groupPosition) {
return data.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return data.get(groupPosition).getList().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
//二级
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
final GroupHolder holder;
if (convertView==null){
convertView = View.inflate(context, R.layout.buju,null);
holder = new GroupHolder();
holder.check = convertView.findViewById(R.id.check);
holder.title = convertView.findViewById(R.id.title);
convertView.setTag(holder);
}else{
holder = (GroupHolder) convertView.getTag();
}
//二级列表赋值
//多选框和名字
//获得二级条目的名字
final GoodsBean.DataBean dataBean = data.get(groupPosition);
holder.check.setChecked(data.get(groupPosition).isGroup_check());
holder.title.setText(data.get(groupPosition).getSellerName());
//多选框的点击事件
//到下面与二级子条目想连接
//默认选中的话取消不了
holder.check.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//定义一个变量
childIndex = 0;
//传入点击事件和二级条目的bean集合
childCheck(holder.check.isChecked(),dataBean);
}
});
return convertView;
}
//点击二级的多选框
//默认选中的取消不了
private void childCheck(final boolean checked, final GoodsBean.DataBean dataBean) {
//更新 传入变量的值
GoodsBean.DataBean.ListBean listBean = dataBean.getList().get(childIndex);
Map<String,String> params = new HashMap<>();
params.put("sellerid", String.valueOf(listBean.getSellerid()));
params.put("pid", String.valueOf(listBean.getPid()));
params.put("selected", String.valueOf(checked ? 1 : 0));
params.put("num", String.valueOf(listBean.getNum()));
ApiServers api = HttpUtils.getInstance("http://120.27.23.105/product/").getApi();
api.update(75,params).enqueue(new Callback<UpBean>() {
@Override
public void onResponse(Call<UpBean> call, Response<UpBean> response) {
//点击更新条目进行京东数据更新
childIndex++;
if (childIndex< dataBean.getList().size()){
childCheck(checked,dataBean);
}else{
//传入到p城的网址
myPresenterView.setNet("http://120.27.23.105/product/");
}
}
@Override
public void onFailure(Call<UpBean> call, Throwable t) { } }); }
//二级子列表
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final MyHolder holder;
if(convertView==null){
convertView = View.inflate(context, R.layout.bujuer,null);
holder = new MyHolder();
holder.cb = convertView.findViewById(R.id.cb);
holder.jia =convertView.findViewById(R.id.jia);
holder.jian = convertView.findViewById(R.id.jian);
holder.name = convertView.findViewById(R.id.name);
holder.price = convertView.findViewById(R.id.price);
holder.zong = convertView.findViewById(R.id.zong);
holder.sim = convertView.findViewById(R.id.sim);
holder.text_delete = convertView.findViewById(R.id.text_delete);
convertView.setTag(holder);
}else{
holder = (MyHolder) convertView.getTag();
}
//赋值 或许二级列表的子条目的数据
final GoodsBean.DataBean.ListBean listBean = data.get(groupPosition).getList().get(childPosition);
holder.cb.setChecked(listBean.getSelected()==0 ? false:true);
String[] split = listBean.getImages().split("\\|");
Uri uri = Uri.parse(split[0]);
holder.sim.setImageURI(uri);
holder.name.setText(listBean.getTitle());
holder.price.setText("¥"+
listBean.getBargainPrice()
); holder.zong.setText(listBean.getNum()+"");
//二级子条目的多选框点击事件 更新
//点击子条目的二级列表进行子条目所有全选 以及主页面的全选
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Map<String, String> params=new HashMap<>();
params.put("sellerid", String.valueOf(listBean.getSellerid()));
params.put("pid", String.valueOf(listBean.getPid()));
params.put("selected", String.valueOf(listBean.getSelected()==0 ? 1 : 0));
params.put("num", String.valueOf(listBean.getNum()));
ApiServers api = HttpUtils.getInstance("http://120.27.23.105/product/").getApi();
api.update(75,params).enqueue(new Callback<UpBean>() {
@Override
public void onResponse(Call<UpBean> call, Response<UpBean> response) {
if (response.isSuccessful()){
//调用网址 myPresenterView.setNet("http://120.27.23.105/product/");
}
}
@Override
public void onFailure(Call<UpBean> call, Throwable t) { } }); } });
//加
holder.jia.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Map<String, String> params=new HashMap<>();
params.put("sellerid", String.valueOf(listBean.getSellerid()));
params.put("pid", String.valueOf(listBean.getPid()));
params.put("selected", String.valueOf(listBean.getSelected()));
params.put("num", String.valueOf(listBean.getNum()+1));
ApiServers api = HttpUtils.getInstance("http://120.27.23.105/product/").getApi();
api.update(75,params).enqueue(new Callback<UpBean>() {
@Override
public void onResponse(Call<UpBean> call, Response<UpBean> response) {
if (response.isSuccessful()){
myPresenterView.setNet("http://120.27.23.105/product/");
}
}
@Override
public void onFailure(Call<UpBean> call, Throwable t) { } }); } });
//减
holder.jian.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//判断如果减到一就不能再减了
int num=listBean.getNum();
if (num==1){
return;
}
Map<String, String> params=new HashMap<>();
params.put("sellerid", String.valueOf(listBean.getSellerid()));
params.put("pid", String.valueOf(listBean.getPid()));
params.put("selected", String.valueOf(listBean.getSelected()));
params.put("num", String.valueOf(num-1));
ApiServers api = HttpUtils.getInstance("http://120.27.23.105/product/").getApi();
api.update(75,params).enqueue(new Callback<UpBean>() {
@Override
public void onResponse(Call<UpBean> call, Response<UpBean> response) {
if (response.isSuccessful()){
myPresenterView.setNet("http://120.27.23.105/product/");
}
}
@Override
public void onFailure(Call<UpBean> call, Throwable t) { } }); } });
//删除
holder.text_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String pid = String.valueOf(listBean.getPid());
ApiServers api = HttpUtils.getInstance("http://120.27.23.105/product/").getApi();
api.del("75",pid).enqueue(new Callback<DeleteBean>() {
@Override
public void onResponse(Call<DeleteBean> call, Response<DeleteBean> response) {
if (response.isSuccessful()){
myPresenterView.setNet("http://120.27.23.105/product/");
}
}
}
@Override
public void onFailure(Call<DeleteBean> call, Throwable t) { } }); } });
return convertView;
}
//总价 返回到主界面
public void sendPriceAndCount() {
//价格和数量
double price=0; int count=0; for (int i=0;i<data.size();i++){
List<GoodsBean.DataBean.ListBean> listBeans = data.get(i).getList();
for (int j=0;j<listBeans.size();j++){
if (listBeans.get(j).getSelected()==1) {
//价格和数量相乘
price +=listBeans.get(j).getBargainPrice() * listBeans.get(j).getNum();
//数量
count +=listBeans.get(j).getNum();
}
}
}
//创建bean类 把总价和数量传入
//到时候我们会返回到主界面进行handler赋值
DecimalFormat decimalFormat = new DecimalFormat("0.00");
String priceString = decimalFormat.format(price);
CountPriceBean countPriceBean = new CountPriceBean(priceString, count);
Message msg=Message.obtain();
msg.what=0; msg.obj=countPriceBean;
handler.sendMessage(msg);
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
//主界面全选 添加到集合里面 返回到主界面
public void isAllCheckChild(boolean checked) {
List<GoodsBean.DataBean.ListBean> allList = new ArrayList<>();
for (int i=0;i<data.size();i++){
GoodsBean.DataBean dataBean = data.get(i);
for (int j=0;j<dataBean.getList().size();j++){
GoodsBean.DataBean.ListBean listBean = dataBean.getList().get(j);
allList.add(listBean);
}
}
allIndex = 0;
updateAllChildCheck(checked,allList);
}
//更新
private void updateAllChildCheck(final boolean checked, final List<GoodsBean.DataBean.ListBean> allList) {
final GoodsBean.DataBean.ListBean listBean = allList.get(allIndex);
Map<String,String> params = new HashMap<>();
//查询
params.put("sellerid", String.valueOf(listBean.getSellerid()));
params.put("pid", String.valueOf(listBean.getPid()));
params.put("selected", String.valueOf(checked ? 1 : 0));
params.put("num", String.valueOf(listBean.getNum()));
ApiServers api = HttpUtils.getInstance("http://120.27.23.105/product/").getApi();
api.update(75,params).enqueue(new Callback<UpBean>() {
@Override
public void onResponse(Call<UpBean> call, Response<UpBean> response) {
allIndex++;
if (allIndex< allList.size()){ updateAllChildCheck(checked,allList);
}else{
myPresenterView.setNet("http://120.27.23.105/product/");
}
}
@Override
public void onFailure(Call<UpBean> call, Throwable t) { } });
}
class MyHolder{
CheckBox cb;
TextView name;
TextView price;
TextView zong;
TextView jia,jian;
TextView text_delete;
SimpleDraweeView sim;
}
class GroupHolder{
CheckBox check; TextView title;
}
}