您好,登錄后才能下訂單哦!
這篇文章主要介紹“Android如何實現簡單購物車”,在日常操作中,相信很多人在Android如何實現簡單購物車問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Android如何實現簡單購物車”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
1、CheckBox的聯動:
全選框、商鋪復選框以及商品復選框要做到滴水不漏的聯動,我的經驗是在監聽多選框時盡量采用click事件,避免使用checkChange事件(因為它總是能在你意想不到的地方調用),全選框可以通過商品價格來判斷,這個在代碼中也有體現。
2、數據的聯動和UI的聯動:
適配器的都是在外部類創建,而總價格等控件都是在調用適配器的地方,這個要做到聯動,最簡單的方式必然就是接口的回調,熟練使用可以節省很多代碼,提高編程效率。
再有一個比較容易出現問題的地方就在于,我們經常是首先更改數據,然后通知適配器刷新數據(notifyDataSetChanged()),這里要注意的一點就是在更新數據的時候,一定確保更新的傳遞到適配器中的數據集合,否則會發現這個更新適配器的方法是無效的。
其他相關問題代碼中均有體現,如果和我一樣是一個編程小白,仔細閱讀會有收獲滴。
代碼中沒有添加自己的資源,邏輯都有實現就是UI丑了一點
activity_main:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.bwie.test.test1025two.MainActivity"> <RelativeLayout android:layout_gravity="center_horizontal" android:background="@color/colorAccent" android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:textSize="38sp" android:gravity="center" android:textColor="#fff" android:text="購物車" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:textColor="#fff" android:textSize="38sp" android:layout_alignParentRight="true" android:text="2" android:id="@+id/main_num" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> <ExpandableListView android:layout_weight="1" android:id="@+id/expand_able_view" android:layout_width="match_parent" android:layout_height="match_parent"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <CheckBox android:layout_weight="1" android:id="@+id/main_check_all" android:text="全選" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:id="@+id/main_price" android:gravity="center_horizontal" android:text="0" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_delete" android:background="#aaa" android:layout_weight="1" android:text="刪除" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_buy" android:background="#f99" android:layout_weight="1" android:text="購買" android:layout_width="0dp" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>
group_item:
注:這里圖了個簡單,商鋪名稱我是通過設置CheckBox的text來顯示的,另外取消焦點是為了不影響二級列表的點擊展開與收回子集列表
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <CheckBox android:focusable="false" android:id="@+id/group_check" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
child_item:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <CheckBox android:id="@+id/child_check" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/child_img" android:scaleType="center" android:src="@mipmap/ic_launcher" android:layout_width="80dp" android:layout_height="80dp" /> <TextView android:id="@+id/child_price" android:textSize="22sp" android:textColor="@color/colorPrimary" android:text="2888" android:layout_width="wrap_content" android:layout_height="80dp" /> <RelativeLayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="80dp"> <TextView android:text="名字" android:id="@+id/child_name" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:orientation="horizontal" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/child_jian" android:gravity="center_horizontal" android:text="—" android:layout_width="30dp" android:layout_height="30dp" /> <TextView android:gravity="center_horizontal" android:text="2" android:id="@+id/child_num" android:layout_width="30dp" android:layout_height="30dp" /> <TextView android:id="@+id/child_jia" android:gravity="center_horizontal" android:text="+" android:layout_width="30dp" android:layout_height="30dp" /> </LinearLayout> </RelativeLayout> </LinearLayout>
groupBean:
package com.bwie.test.test1025two; import java.util.ArrayList; /** * Created by Zzw on 2017/10/25. */ public class Group { private String name; private boolean check; private ArrayList<Child> children; public Group(String name, boolean check,ArrayList<Child> children) { this.name = name; this.check = check; this.children = children; } public Group() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isCheck() { return check; } public void setCheck(boolean check) { this.check = check; } public void setChildren(ArrayList<Child> children){ this.children = children; } public ArrayList<Child> getChildren(){ return children; } @Override public String toString() { return "Group{" + "name='" + name + '\'' + ", check=" + check + '}'; } }
childBean:
package com.bwie.test.test1025two; /** * Created by Zzw on 2017/10/25. */ public class Child { private String name; private String img; private int num; private boolean check; private int price; public Child(String name, String img, int num, boolean check, int price) { this.name = name; this.img = img; this.num = num; this.check = check; this.price = price; } public Child() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getImg() { return img; } public void setImg(String img) { this.img = img; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public boolean isCheck() { return check; } public void setCheck(boolean check) { this.check = check; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return "Child{" + "name='" + name + '\'' + ", img='" + img + '\'' + ", num=" + num + ", check=" + check + ", price=" + price + '}'; } }
MyAdapter:
package com.bwie.test.test1025two; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; /** * Created by Zzw on 2017/10/25. */ public class MyAdapter extends BaseExpandableListAdapter { Context context; ArrayList<Group> groups; public MyAdapter(Context context, ArrayList<Group> groups) { this.context = context; this.groups = groups; } //監聽加減事件回調接口 public interface onNumChangeListener{ void onNumChange(int groupID,int childID,boolean isAdd); } private onNumChangeListener mOnNumChangeListener; public void setOnNumChangeListener(onNumChangeListener mOnNumChangeListener){ this.mOnNumChangeListener = mOnNumChangeListener; } //監聽多選框點擊事件回調接口。 public interface onCheckChangeListener{ void onGroupClick(int groupID); void onChildClick(int groupID,int childID); } private onCheckChangeListener mOnCheckChangeListener; public void setmOnCheckChangeListener(onCheckChangeListener mOnCheckChangeListener){ this.mOnCheckChangeListener = mOnCheckChangeListener; } //監聽價格需要更新回調接口 public interface onShouldChangeMoneyListener{ void onShouldChnageMoney(); } private onShouldChangeMoneyListener mOnShouldChangeMoneyListener; public void setmOnShouldChangeMoneyListener(onShouldChangeMoneyListener mOnShouldChangeMoneyListener){ this.mOnShouldChangeMoneyListener = mOnShouldChangeMoneyListener; } @Override public int getGroupCount() { return groups.size(); } @Override public int getChildrenCount(int i) { return groups.get(i).getChildren().size(); } @Override public Object getGroup(int i) { return groups.get(i); } @Override public Object getChild(int i, int i1) { return groups.get(i).getChildren().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 View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) { GroupHolder holder = null; if (view == null){ view = LayoutInflater.from(context).inflate(R.layout.group_item,viewGroup,false); holder = new GroupHolder(); holder.checkBox = (CheckBox) view.findViewById(R.id.group_check); view.setTag(holder); }else{ holder = (GroupHolder) view.getTag(); } holder.checkBox.setText(groups.get(i).getName()); holder.checkBox.setChecked(groups.get(i).isCheck()); if (mOnCheckChangeListener != null&&mOnShouldChangeMoneyListener != null){ holder.checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnCheckChangeListener.onGroupClick(i); mOnShouldChangeMoneyListener.onShouldChnageMoney(); } }); } return view; } @Override public View getChildView(final int i,final int i1, boolean b, View view, ViewGroup viewGroup) { ChildHolder holder = null; if (view == null){ view = LayoutInflater.from(context).inflate(R.layout.child_item,viewGroup,false); holder = new ChildHolder(); holder.checkBox = (CheckBox) view.findViewById(R.id.child_check); holder.imageView = (ImageView) view.findViewById(R.id.child_img); holder.name = (TextView) view.findViewById(R.id.child_name); holder.num = (TextView) view.findViewById(R.id.child_num); holder.jian = (TextView) view.findViewById(R.id.child_jian); holder.jia = (TextView) view.findViewById(R.id.child_jia); holder.price = (TextView) view.findViewById(R.id.child_price); view.setTag(holder); }else{ holder = (ChildHolder) view.getTag(); } holder.checkBox.setChecked(groups.get(i).getChildren().get(i1).isCheck()); holder.imageView.setImageResource(R.mipmap.ic_launcher); holder.name.setText(groups.get(i).getChildren().get(i1).getName()); holder.num.setText(groups.get(i).getChildren().get(i1).getNum()+""); holder.price.setText(groups.get(i).getChildren().get(i1).getPrice()+""); if (mOnNumChangeListener != null&&mOnShouldChangeMoneyListener != null){ holder.jian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnNumChangeListener.onNumChange(i,i1,false); mOnShouldChangeMoneyListener.onShouldChnageMoney(); } }); } if (mOnNumChangeListener != null&&mOnShouldChangeMoneyListener != null){ holder.jia.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnNumChangeListener.onNumChange(i,i1,true); mOnShouldChangeMoneyListener.onShouldChnageMoney(); } }); } if (mOnCheckChangeListener != null&&mOnShouldChangeMoneyListener != null){ holder.checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnCheckChangeListener.onChildClick(i,i1); mOnShouldChangeMoneyListener.onShouldChnageMoney(); } }); } return view; } @Override public boolean isChildSelectable(int i, int i1) { return true; } class GroupHolder { CheckBox checkBox; } class ChildHolder{ CheckBox checkBox; ImageView imageView; TextView name,num,jian,jia,price; } }
MainActivity:
package com.bwie.test.test1025two; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.ExpandableListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { TextView num,price;//右上角當前商品數量和底部當前已選中商品的價格 ExpandableListView expandableListView;//展示商品信息的二級列表 CheckBox checkAll;//左下角全選 Button btnDel,btnBuy;//底部刪除當前選中按鈕、購買按鈕 ArrayList<Group> groups = new ArrayList<>();//數據源集合 MyAdapter adapter;//自定義baseExpandable適配器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView();//控件初始化 initData();//數據初始化 changeGoodsNum();//初始化當前商品個數。 /** * 自定義加減按鈕回調 * params: groupID:商鋪id childID:商品在當前商鋪的id isADD:非加即減 */ adapter.setOnNumChangeListener(new MyAdapter.onNumChangeListener() { @Override public void onNumChange(int groupID, int childID, boolean isAdd) { //獲得當前點擊商品的數量 int num = groups.get(groupID).getChildren().get(childID).getNum(); if (isAdd){//加 //在數據源中該商品數量自增1 groups.get(groupID).getChildren().get(childID).setNum(++num); }else{//減 if (num == 1){//數量為1給出提示 Toast.makeText(MainActivity.this, "受不了了,不能再少了", Toast.LENGTH_SHORT).show(); }else{//在數據源中該商品數量自減1 groups.get(groupID).getChildren().get(childID).setNum(--num); } } //更新UI adapter.notifyDataSetChanged(); changeMoney();//更新價格顯示 } }); //自定義商鋪和商品多選框點擊回調 adapter.setmOnCheckChangeListener(new MyAdapter.onCheckChangeListener() { @Override public void onGroupClick(int groupID) {//組點擊 //將數據源置反,以保持同步 groups.get(groupID).setCheck(!(groups.get(groupID).isCheck())); //獲取當前選中狀態 boolean flag = groups.get(groupID).isCheck(); //更新其下所有商品CheckBox for (int i = 0 ; i < groups.get(groupID).getChildren().size(); i++){ groups.get(groupID).getChildren().get(i).setCheck(flag); } //更新UI adapter.notifyDataSetChanged(); //更新價格顯示 changeMoney(); } @Override public void onChildClick(int groupID, int childID) {//商品點擊 //將數據源置反以保持同步 groups.get(groupID).getChildren().get(childID).setCheck(!(groups.get(groupID).getChildren().get(childID).isCheck())); //判斷該條目及所有兄弟條目是否全部選中,以及時更新商鋪CheckBox int flag = 0; for (int i = 0 ; i < groups.get(groupID).getChildren().size() ; i++){ if (groups.get(groupID).getChildren().get(i).isCheck()){ flag++; } } //如果該組下的選中數量與該集合長度相等,說明全部選中,更新組CheckBox if (flag == groups.get(groupID).getChildren().size()){ groups.get(groupID).setCheck(true); }else{ groups.get(groupID).setCheck(false); } //更新UI adapter.notifyDataSetChanged(); //更新價格顯示 changeMoney(); } }); //刪除按鈕點擊 btnDel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { List<Group> toBeDeleteGroups = new ArrayList<Group>();// 待刪除的組元素列表 for (int i = 0; i < groups.size(); i++) { Group group = groups.get(i); if (group.isCheck()) { toBeDeleteGroups.add(group); } List<Child> toBeDeleteChildren = new ArrayList<Child>();// 待刪除的子元素列表 List<Child> childs = group.getChildren(); for (int j = 0; j < childs.size(); j++) { if (childs.get(j).isCheck()) { toBeDeleteChildren.add(childs.get(j)); } } childs.removeAll(toBeDeleteChildren); } groups.removeAll(toBeDeleteGroups); //更新UI adapter.notifyDataSetChanged(); //更新當前商品數量顯示 changeGoodsNum(); //更新當前價格顯示 changeMoney(); } }); //購買按鈕,點擊提示當前選中金額 btnBuy.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String money = price.getText().toString(); Toast.makeText(MainActivity.this, "當前總金額:"+money, Toast.LENGTH_SHORT).show(); } }); //全選按鈕,點擊更新視圖所有CheckBox checkAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { for (int i = 0 ; i< groups.size() ; i++){ groups.get(i).setCheck(checkAll.isChecked()); for (int j = 0 ; j < groups.get(i).getChildren().size() ; j ++){ groups.get(i).getChildren().get(j).setCheck(checkAll.isChecked()); } } //更新UI adapter.notifyDataSetChanged(); //更新總價顯示 changeMoney(); } }); //自定義回調更新總價 adapter.setmOnShouldChangeMoneyListener(new MyAdapter.onShouldChangeMoneyListener() { @Override public void onShouldChnageMoney() { //更新總價顯示 changeMoney(); } }); } //初始化數據,設置適配器 private void initData() { for (int i = 0 ; i < 5 ; i++){ ArrayList<Child> children = new ArrayList<>(); for (int j = 0 ; j <= i ; j++){ children.add(new Child("店鋪"+i+"的商品:"+j,"",2,false,j+1)); } groups.add(new Group("商鋪:"+i,false,children)); } adapter = new MyAdapter(this,groups); expandableListView.setAdapter(adapter); for (int i = 0; i < groups.size(); i++) { expandableListView.expandGroup(i);// 初始化時,將ExpandableListView以展開的方式呈現 } } //獲得控件資源 private void initView() { num = (TextView) findViewById(R.id.main_num); expandableListView = (ExpandableListView) findViewById(R.id.expand_able_view); checkAll = (CheckBox) findViewById(R.id.main_check_all); btnDel = (Button) findViewById(R.id.btn_delete); btnBuy = (Button) findViewById(R.id.btn_buy); price = (TextView) findViewById(R.id.main_price); } //當前購物車商品數量 private void changeGoodsNum(){ int currentNum = 0; for (int i = 0 ; i < groups.size(); i++){ for (int j = 0 ; j < groups.get(i).getChildren().size(); j++){ currentNum++; } } num.setText(currentNum+""); } //更新總價 private void changeMoney(){ int money = 0; int allMoney = 0;//獲得當前全部商品價格 for (int i = 0 ; i < groups.size(); i++){ for (int j = 0 ; j < groups.get(i).getChildren().size(); j++){ if (groups.get(i).getChildren().get(j).isCheck()){ money += groups.get(i).getChildren().get(j).getNum() * groups.get(i).getChildren().get(j).getPrice(); } allMoney += groups.get(i).getChildren().get(j).getNum() * groups.get(i).getChildren().get(j).getPrice(); } } //當選中價格與全部價格相等,更新全選框 if (money == allMoney){ checkAll.setChecked(true); }else{ checkAll.setChecked(false); } price.setText(money + ""); } }
效果圖:
到此,關于“Android如何實現簡單購物車”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。