<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了Android實現簡單購物車的具體程式碼,供大家參考,具體內容如下
這裡我用到的都是Android自帶SDK中的資源,做了一個極其簡單的購物車實現,總結購物車難點包含兩個方面:
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 + ""); } }
效果圖:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45