Android学习之网上商城(下)
前言
上一篇博客主要介紹了本次網上商城的實現過程中的一些用法,這篇博客主要就是說明每個功能模式的實現方法
Android學習之網上商城(上)
Android學習之網上商城(下)
源碼下載:
鏈接:https://pan.baidu.com/s/1Z17xBHV9iq70LwdgXxwDIQ
提取碼:Lin2
Android學習之網上商城源代碼
本博客內容原創,創作不易,轉載請注明
本文鏈接
個人博客:https://ronglin.fun/?p=120
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/121876819
開發環境:
- Android Studio版本:(Android Studio Arctic Fox 2020.3.1 Patch 3)
- SDK版本:(Android 7.0 API24 Revision 2)
- Gradle版本:(7.0.2)
- Android Gradle Plugin版本:(7.0.3)
文件布局如下:
數據結構
Goods
對于每一個商品類,提供以下的成員變量
private ArrayList<Bitmap> bitmaps;private String goodsName;private String describe;private ArrayList<String> tags;private int price;public static ArrayList<Goods> GOODSLIST =new ArrayList<>();public static Goods DEULT_GOODS = new Goods();簡單介紹一下,price變量是一個以分為單位的數,比如10000就是100.00元,這樣就不會涉及到浮點數的精度問題,bitmaps是一個圖片的合集,用來保存商品的一些預覽圖,其他就見名知意了。然后DEULT_GOODS默認商品類就是一個有內存但是沒有數據的類
構造方法如下:
public Goods(){this.bitmaps = new ArrayList<>();this.goodsName = "";this.describe = "";this.tags = new ArrayList<>();this.price = -1;}public Goods(String goodsName, String describe, String[] tags, int price){...}除了成員變量的getter方法和setter方法還有以下方法:
public boolean equals(Goods goods){return this.getGoodsName().equals(goods.getGoodsName())&& this.getTags().equals(goods.getTags())&& this.getDescribe().equals(goods.getDescribe())&& this.getPrice() == goods.getPrice();}public static String toPriceString(int price){StringBuffer sb = new StringBuffer(String.valueOf(price));//小于2位數if (sb.length()<=2){if (sb.length() == 0){sb.insert(0,"0.00");} else if(sb.length() == 1){sb.insert(0,"0.0");} else if(sb.length() == 2){sb.insert(0,"0.");}} else {sb.insert(sb.length()-2,'.');}return sb.toString();}public static void getDefaultGoodsList(Context context)equals方法就是判斷兩個Goods是否相等.
toPriceString是因為price是以分為單位的數據,要把它變成以元為單位的,例如:
10000 -> 100.00;
0 -> 0.00;
10 -> 0.10;
getDefaultGoodsList就是用來初始化商品列表的
Person
person類是一個封裝用戶信息的一個類
成員變量如下:
構造方法如下
public Person(String name, String password){this.username = name;this.password = password;}需要注意的是,這個類中并沒有對person的id和num進行初始化,所以說當要插入數據庫時,要先在數據庫中獲取id和num值,對于這兩個值的意義在數據庫設計中會有說明.
除了成員變量的getter方法和setter方法還有以下方法:
主要就是將一個person的數據輸出
數據庫
表格設計
數據庫的設計是核心,因為采用本地數據存儲,所有數據要保存在本地數據庫中,接下來簡單說明一下本次數據庫設計
本次數據庫一共新建了兩個表格,如下
第一個表格是person表,元組有id(主鍵),num、username、password,四個,id和num是一樣的,但是數據類型不一樣,主要是為了區分用戶名相同的用戶,num表示當前第多少個用戶,例如是第一個注冊的,那么id = num =1,第二個注冊的就是id = num =2,以此類推。
第二個表格是shopping表,用來保存用戶的歷史訂單的,元組有id、goodsName、time,其中id就是person表格中的id,goodsName是商品名稱,time則是用戶購買商品的時間戳,采用的是java的時間戳格式,是一個long類型的相對于1970年開始的毫秒值。因為一個用戶可能購買多個同一商品,所以說要加一個time用來區分。
代碼設計
主要設計了以下方法
public class Database {private MySQLiteHelper mySQLiteHelper;private SQLiteDatabase database;public Database(MySQLiteHelper mySQLiteHelper){this.mySQLiteHelper = mySQLiteHelper;}//將person插入數據庫public void insertPersonToSQLite(Person person){...}//獲取當前數據庫中的最大Numpublic int getPersonMaxNumFromSQLite(){...}//根據id更新數據public int updatePersonToSQLite(Person person){...}//刪除personpublic int deletePersonToSQLite(Person person){...}//此方法用來查詢數據庫中是否存在person//優先查詢id,id==null,查詢username//password為空時返回第一個username的信息 不為空時匹配用戶名和密碼//當查詢不到時返回nullpublic Person findPersonFromSQLite(String id,String username,String password){...}//插入購物清單public void insertGoodsToSQLite(Person person,Goods goods,long time){...}//刪除購物項public int deleteGoodsToSQLite(Person person,Goods goods){...}//查person的所有購物項public ArrayList<String> findGoodsListFromSQLite(Person person){...} }注意要想插入person的時候,要先調用getPersonMaxNumFromSQLite方法獲取MaxNum來設置person的id和num數據
注冊登錄
登錄界面
效果如圖:
這個界面主要是2個EditText和2個Button,注冊按鈕的監聽方法就是點擊后會跳轉到注冊的Activity,調用的是startActivityForResult();方法,因為需要注冊界面把注冊用戶的信息返回回來,然后在onActivityResult()方法中將2個EditText的內容填好。登錄按鈕就是點擊之后,先檢查用戶輸入是否合理,例如:是否輸入了密碼等,如果沒輸入就提示一個Toast,如果輸入合法,就在本地數據庫中查詢,如果不存在提示Toast,如果登錄成功,則把當前的界面中的控件用setVisibility()方法隱藏,然后顯示登錄成功界面。
注冊界面
登錄界面比較簡單,是一個單獨的Activity,功能主要是,點擊取消當前界面finish(),如果點擊注冊核對用戶輸入是否合法,合法的話,將數據插入數據庫,插入之前要先檢測一下是否在數據庫中存在當前用戶,標準是用戶名和密碼同時對應,如果存在提示一個Toast,不存在則插入數據庫,然后將數據通過setResult()方法傳回MainActivity。
登錄成功界面
登錄成功界面是和登錄界面同時存在的,一開始是隱藏起來的一個線性布局,等登錄成功之后,從數據庫中獲取用戶的余額和歷史清單,然后將數據顯示出來,也是比較簡單。
因為數據庫中存儲的是貨物的名稱,當獲取名稱之后,還要通過當前的貨物List查詢出來每一個貨物,將String類型的數據轉化為Goods類型。
充值按鈕就是增加100元給當前賬戶,同時更新到數據庫中,注銷就是退出當前賬戶.但是實際上并沒有退出,而是把當前界面隱藏然后顯示登錄界面.
然后購物清單就是一個從數據庫中獲取數據的一個ListView
商品展示
這是商品展示界面,布局主要是一個頂部欄和一個ListVeiw.還有響應點擊會彈出一個有關商品的詳細信息的對話框
頂部欄
頂部欄其中有三個控件,從左到右分別是 用戶 搜索框 購物車,點擊用戶按鈕則跳轉到個人中心的Fragment,用法如下:
Navigation.findNavController(GoodsFragment.this.getView()).navigate(R.id.navigation_person);搜索框實現了一個實時查詢的功能,用到了TextWatcher類,關于這個類的用法在前邊有詳細說明,當用戶輸入一個字符之后就開始搜索,搜索范圍為一個商品的字符成員變量,Tag goodsName,describe代碼如下:
@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {String search = s.toString().trim();if(search.isEmpty()){goodsViewModel.setListGoods(list);} else {resultList.clear();for (Goods t:list) {if(t.getGoodsName().contains(search)){resultList.add(t);} else if (t.getTags().toString().contains(search)){resultList.add(t);} else if (t.getDescribe().contains(search)){resultList.add(t);}}goodsViewModel.setListGoods(resultList);}}ListView
listView中的重點就是adapter類的書寫,在前面有了詳細說明
public class GoodsListAdapter extends BaseAdapter同時有關點擊每一個item彈出對話框也是在這個類里調用setOnClickListener方法實現.
還有點擊"+“將當前貨物添加到購物車中也是在GoodsListAdapter類中實現
同時還有一個延遲效果,點擊”+“之后圖標變成 “√” 然后經過1s之后變回”+",在這一秒內用戶無法添加貨物到購物車,這延遲的實現方法用的是前面介紹的 單線程實現定時器
商品詳細對話框
樣式如上
一個自定義的對話框,代碼框架如下
就一個主要的數據就是一個Goods類,然后就是實現,點擊任何地方隱藏當前對話框
購物車
主要界面如下
主要是設計為ListView加一個底邊欄
ListView
關于這個ListView的BaseAdapter類,我是這樣定義的
public class ShoppingListAdapter extends BaseAdapter {private ArrayList<Goods> list_goods ;private static ArrayList<Integer> list_select = new ArrayList<>();private int allPrice = 0;private final Context context;private FragmentShoppingBinding binding;public ShoppingListAdapter(ArrayList<Goods> list, Context context, FragmentShoppingBinding binding){this.list_goods = list;this.context = context;this.binding = binding;}//...... }這個listView有一個難點就是要標記選中,因此我用了兩個ArrayList,一個是當前的商品列表,還有一個是選中的項目,這個選中的項目列表存儲的標號index,比如上圖,list_select中存儲的就是[0,1]兩個元素
第二個難點就是要計算出選中的項目的價格,這個是用allPrice變量維護的,然后當list_select變換的時候,就更新一些愛,然后通過傳進來的FragmentShoppingBinding引用來顯示到底邊欄上
底邊欄
難點是刪除按鈕的邏輯,我是這樣設計的,現根據ShoppingListAdapter類中的list_select列表數據,將顯示的list_goods中的Goods先設置成DEULT_GOODS,因為DEULT_GOODS是沒有意義的,然后再用一個方法將list_goods中的所有的DEULT_GOODS刪除,然后再刷新一次界面,就可以了.
刪除功能的結果展示如下:
然后就是全選按鈕,全選按鈕中的邏輯比較簡單,就是修改ShoppingListAdapter類中的list_select數據,將內容設置為全部,同時每一個item中的單選按鈕根據list_select更改選中狀態,即可
最后就是購買按鈕,效果如下:
效果為點擊購買,之后彈出一個對話框,對話框的內容為確定付款,顯示用戶當前所擁有的金額和購買商品所需要的金額,如果用戶點擊確定,則比較兩個金額,用戶余額不夠的話提示一個Toast,夠的話就在購物車中刪除對應的item,然后將對應的Goods數據插入數據庫中,將相應的金額扣除,更新數據庫中的用戶數據
總結
至此,一個簡易的網上商城APP就做完了,難點在于新得框架的應用和一些功能的時間方法,還有界面設計的美觀性和應對不同屏幕大小的適配.
總之,本次課設收獲良多,但是無奈兩周時間趕上3門考試,一邊考試一邊課設精力有限,界面簡陋,功能簡單,不過主要以學習為主.經過本次課設,對于Android開發過程有了大概的理解,獲益良多,=w=
總結
以上是生活随笔為你收集整理的Android学习之网上商城(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python列表输入10个数、并排序-我
- 下一篇: urlconnection java_J