小工具知识网

当前位置: 首页 > 行业知识 > Android课程设计-网上商城/外卖小助手(仿美团外卖)

行业知识

Android课程设计-网上商城/外卖小助手(仿美团外卖)

2026-11-03 01:19:31 来源:互联网转载

目录

前言

1 实验题目

2 实验目的

3 实验内容

3.1 要求

3.2 模块介绍

3.3 设计步骤或关键代码

3.3.1 SQlite数据库

3.2.2 创建店铺和商品的json文件,以及对应的Service解析类

3.2.3 读取并解析shop.json文件

3.2.4 根据shop.json文件中的brandStrId读取对应raw文件夹下的商品.json文件

3.2.5 ListView控件

4 实验结果与分析

5 代码

5.1 Android代码

5.2 Idea服务器代码


前言

        本实验为Android课程设计内容,最初的原型是书上的给宠物购买装备的项目,因为那里面有页面跳转的实现,后面因为有一个仿美团外卖大作业的需求,就按照老师给的ppt里面的界面一点一点的自己写布局文件,尽量搞的像了一点,再后来就是到了Android课设了,需要更多的功能以及登陆注册就把书上一个注册登录和Android应用市场的项目也整合进来了,同时,新增了结算和历史订单查询的界面。该博客的许多内容为部分报告内容,仅为大家提供参考,请勿直接抄袭。另外,本次实验所用平台是Android Studio 2022.3.1版本,服务器端是Idea,因为我之前写mvc结构感觉有点麻烦,暑假就学了点springboot,所以本次服务器采用的是springboot框架

        最开始的本版用户和订单数据是存放在文件里面的,因为我写的慢,听说别人搞了本地SQLite,我写了SQLite存储的版本,后面又听说别人搞了与本地服务器交互的存储在mysql的,所以我最后是打算搞一个mysql和SQLite同步的,但是由于时间问题,服务器写完了,但是Android这边没写完,只写了User数据同步的,其他的订单和商店信息并没有实现,有能力的同学可以尝试写完整,并且,我就是只做了要求的,而且还没全部实现,没有自己加功能,希望大家能搞定的,尽量自己想写新功能,比如商店管理,菜品管理等一些功能,尽量搞点创意,这样才能拿个好成绩

        在运行项目时,必须先把后端服务器先启动,因为我在Login和Register两个Activity里面是写了和服务器同步的,如果不想搞复杂,可以找到两个Activity里面的和服务器相关的代码注释掉,这部分我基本上注释掉了,还是比较简单理解的

1 实验题目

        网上商城/外卖小助手

2 实验目的

        (1)掌握 Android 中的菜单及导航框架。

        (2)掌握自定义布局。

        (3)掌握 Android 中的数据存储。

3 实验内容

3.1 要求

        (1)要求实现商品展示、商品详细介绍、下订单、购物车。

        (2)要求实现用户注册、登录、查看历时订单。

        (3)数据:可以采用静态的固定的数据来模拟(如果动手能力较强,可以尝试自己动手搭后台,利用 Android 网络编程)。

3.2 模块介绍

        (1)注册模块:注册用户。

        (2)登录模块:用户登录平台。

        (3)店铺浏览模块:查看平台已有店铺,注意是提前卸载文件里面的,时间问题没有做到SQLite存储,大家可以自己尝试,比较简单。

        (4)个人中心模块:在店铺浏览模块点击个人中心的图标后会进入,可以充值和查看历史订单。

        (5)点单模块:点击进入店铺后可以下单。

        (6)结算模块:点击结算之后,进入结算界面。

3.3 设计步骤或关键代码

        在这个部分,我主要讲一些我认为比较重要的地方

3.3.1 SQlite数据库

        (1)设计一个数据库操作类MyHelper,然后利用该类创建网上商城/外卖小助手的Android Studio自带的SQLite数据库takeaway1.db,利用MySQL的可视化工具Navicat创建网上商城/外卖小助手后端服务器的需要的数据库infodb。然后分别在两个数据库中创建相应的表项,如用户表user和历史订单表historical_order等。

        (2)代码主要是在这里面主要是需要让MyHelper类继承SQLiteOpenHelper类,然后重写相应方法即可,可以参考书上SQLite数据库部分

package com.wx.mytakeout.utils;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.util.Log;public class MyHelper extends SQLiteOpenHelper {    private static final String Tag = "MyHelper";    public MyHelper(Context context){        super(context,"takeaway1.db",null,1);        Log.i(Tag,"创建数据库 takeaway1");    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL("create table user(_id integer primary key autoincrement," +                "username varchar(20),password varchar(20),money int)");        db.execSQL("create table historical_order(_id integer primary key autoincrement," +                "orderId int,username varchar(20),userTel varchar(11),userAddress varchar(20)," +                "goodsId integer,goodsName varchar(30),goodsCount int,goodsPrice int,deliveryCost int, orderPrice int)");        db.execSQL("CREATE TABLE shop (id integer primary key autoincrement," +                "  brandStrId varchar(10)  ,brandName varchar(20)  ," +                "  brandSales varchar(20)  ,startDeliveryCost int  ," +                "  deliveryCost int  , brandEvaluation varchar(30)  ," +                "  deliveryTime int ,announcement varchar(30) )");        db.execSQL("CREATE TABLE goods (id integer primary key autoincrement," +                "  brandStrId varchar(10) ,goodsStrId varchar(10)  ," +                "  goodsName varchar(30) ,goodsSales varchar(20) ," +                "  goodsFavourableComment varchar(20) , goodsEvaluation varchar(20)  ," +                "  goodsPrice int  )");        Log.i(Tag,"创建表 user 和 historical_order");    }    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {    }}

3.2.2 创建店铺和商品的json文件,以及对应的Service解析类

        (1)创建对应店铺或者商品的json文件,只给出shop.json和mxbc.json,在后面会全部上传可以自行下载

                1)shop.json

[  {"brandStrId":"mxbc", "brandName":"蜜雪冰城","brandSales":"月销2023","startDeliveryCost":15,"deliveryCost":5,"brandEvaluation":"性价比最高,没有之一","deliveryTime":30,"announcement":"价格实惠"},  {"brandStrId":"tst", "brandName":"塔斯汀","brandSales":"月销1023","startDeliveryCost":25,"deliveryCost":2,"brandEvaluation":"中国汉堡","deliveryTime":45,"announcement":"周四疯狂日"},  {"brandStrId":"yht", "brandName":"益禾堂","brandSales":"月销1500","startDeliveryCost":20,"deliveryCost":4,"brandEvaluation":"广外大街饮品任期第3名","deliveryTime":35,"announcement":"奶茶味道不错"},  {"brandStrId":"rxkf", "brandName":"瑞幸咖啡","brandSales":"月销1333","startDeliveryCost":22,"deliveryCost":3,"brandEvaluation":"酱香拿铁,你值得拥有","deliveryTime":30,"announcement":"全场8折"},  {"brandStrId":"bxlxd", "brandName":"百香林西点","brandSales":"月销1533","startDeliveryCost":12,"deliveryCost":2,"brandEvaluation":"蛋糕很好吃,奶油新鲜不腻,水果新鲜","deliveryTime":45,"announcement":"可定制蛋糕"}]

                2)mxb.json

[  {"goodsStrId":"bxnms", "goodsName":"冰鲜柠檬水","goodsSales":"月销336","goodsFavourableComment":"好评度100%","goodsEvaluation":"门店销量第1","goodsPrice":14},  {"goodsStrId":"mtsjc", "goodsName":"蜜桃四季春(升级版)","goodsSales":"月销259","goodsFavourableComment":"好评度86%","goodsEvaluation":"门店销量第2","goodsPrice":17},  {"goodsStrId":"mbbxg", "goodsName":"满杯百香果","goodsSales":"月销228","goodsFavourableComment":"好评度96%","goodsEvaluation":"门店销量第3","goodsPrice":20},  {"goodsStrId":"cmbb", "goodsName":"草莓啵啵","goodsSales":"月销236","goodsFavourableComment":"好评度90%","goodsEvaluation":"门店销量第4","goodsPrice":18}]

        (2)代码

                1)解析shop.json的ShopService 

package com.wx.mytakeout.service;import android.util.Log;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import com.wx.mytakeout.pojo.ShopInfo;import java.io.InputStream;import java.lang.reflect.Type;import java.util.List;public class ShopService {    private static final String Tag = "ShopService";    //获取JSON文件返回shop信息集合    public static List getShopInfosFromJSON(InputStream is) throws Exception {        byte[] buffer = new byte[is.available()];        is.read(buffer);        String json = new String(buffer,"utf-8");        Log.i(Tag,"shopsJson:"+json);        //使用Gson库解析JSON数据        Gson gson = new Gson();        Type listType = new TypeToken(){}.getType();        List shopInfos = gson.fromJson(json,listType);        return shopInfos;    }    //将 string 转为 ShopInfo 类    public static ShopInfo getShopInfoFromStr(String str) throws Exception {        Log.i(Tag,"ShopInfoStr:"+str);        //使用Gson库解析JSON数据        Gson gson = new Gson();        Type strType = new TypeToken(){}.getType();        ShopInfo shopInfo = gson.fromJson(str,strType);        return shopInfo;    }}

                2)解析mxbc.json的GoodsService 

package com.wx.mytakeout.service;import android.util.Log;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import com.wx.mytakeout.pojo.GoodsInfo;import com.wx.mytakeout.pojo.ShopInfo;import java.io.InputStream;import java.lang.reflect.Type;import java.util.List;public class GoodsService {    private static final String Tag = "GoodsService";    //获取JSON文件返回goods信息集合    public static List getGoodsInfosFromJSON(InputStream is) throws Exception {        byte[] buffer = new byte[is.available()];        is.read(buffer);        String json = new String(buffer,"utf-8");        Log.i(Tag,"goodsJson:"+json);        //使用Gson库解析JSON数据        Gson gson = new Gson();        Type listType = new TypeToken(){}.getType();        List GoodsInfos = gson.fromJson(json,listType);        return GoodsInfos;    }    //将 string 转为 GoodsInfo 数组    public static List getGoodsInfosFromStr(String str) throws Exception {        Log.i(Tag,"GoodsInfoStr:"+str);        //使用Gson库解析JSON数据        Gson gson = new Gson();        Type listType = new TypeToken(){}.getType();        List GoodsInfos = gson.fromJson(str,listType);        return GoodsInfos;    }}

3.2.3 读取并解析shop.json文件

        读取shop.json文件,并利用对应json解析函数就行数据解析

                1)在onCreate函数

                //读取 shop.json 文件                InputStream is = this.getResources().openRawResource(R.raw.shop);                //把每个商店的信息集合存到 shopInfos 中                shopInfos = ShopService.getShopInfosFromJSON(is);                for (ShopInfo shopInfo : shopInfos) {                    //Log.i(Tag, "before shopInfo:" + shopInfo);                    shopInfo.setBrandId(getDrawableId(shopInfo.getBrandStrId()));                    Log.i(Tag, "after shopInfo:" + shopInfo);                }

                2)getDrawableId函数:根据shop.json文件中的brandStrId获取对应drawable文件夹下的店铺图片资源

     /**     * 通过 sId 获得对应的 R.drawable 对应的资源     */    public Integer getDrawableId(String sId){        Integer id = null;        try {            Field field = R.drawable.class.getField(sId);            id =field.getInt(field.getName());            //Log.i(Tag, "sId:"+sId+",id:" + id);        } catch (Exception e) {            Log.i(Tag, "解析id失败,sId:"+sId);            e.printStackTrace();        }finally {            return  id;        }    }

3.2.4 根据shop.json文件中的brandStrId读取对应raw文件夹下的商品.json文件

        (1)在3.2.2中的shop.json文件中存储了每个店铺对应的商品存放文件名或图片资源名brandStrId,该部分主要是根据brandStrId在raw文件夹中找到相应的文件,并读取里面的数据,同时利用相应的json解析函数解析数据

        (2)代码

                1)在onCreate函数中,其中的getDrawableId函数是利用某一商品.json文件,如mxbc.json文件中的goodsStrId,获取在drawable文件夹下的图片资源。

                Integer rawId = getRawId(shopInfo.getBrandStrId());                Log.i(Tag, "rawId:" + rawId);                InputStream is = this.getResources().openRawResource(rawId);                //把每个商品的信息集合存到 goodsInfos 中                goodsInfos = GoodsService.getGoodsInfosFromJSON(is);                for (GoodsInfo goodsInfo : goodsInfos) {                    //Log.i(Tag, "before shopInfo:" + shopInfo);                    goodsInfo.setGoodsId(getDrawableId(goodsInfo.getGoodsStrId()));                    Log.i(Tag, "after goodsInfo:" + goodsInfo);                }

                2)getRawId函数

    /**     * 通过 brandStrId 获得对应的 R.raw 对应的资源     */    public Integer getRawId(String brandName) {        Integer id = null;        try {            Field field = R.raw.class.getField(brandName);            id = field.getInt(field.getName());            //Log.i(Tag, "sId:"+sId+",id:" + id);        } catch (Exception e) {            Log.i(Tag, "解析id失败,brandName:" + brandName);            e.printStackTrace();        } finally {            return id;        }    }

3.2.5 ListView控件

        (1)布局文件和效果图

                1)ListView对应的配置文件

                        

                2)ListView对应的效果图

                3)ListView条目对应的布局文件

                            

                4)条目对应的效果图

        (2)数据适配器

                1)在onCreate函数中

                //初始化 ListView 控件                shopListView = (ListView) findViewById(R.id.lv_brand);                //创建一个 Adapter 的实例                MyBaseAdapter myBaseAdapter = new MyBaseAdapter();                //设置 Adapter                shopListView.setAdapter(myBaseAdapter);                //设置 ListView 监听事件,注意是 setOnItemClickListener 不是 setOnClickListener                shopListView.setOnItemClickListener(this);

                2)适配器MyBaseAdapter 继承 BaseAdapter

/**     * 初始化 shop 列表     */    class MyBaseAdapter extends BaseAdapter {        //得到 item 总数        @Override        public int getCount() {            //Log.i(Tag, "当前view数量:"+String.valueOf(shopInfos.size()));            return shopInfos.size();        }        //得到 item 对象        @Override        public Object getItem(int position) {            Log.i(Tag, "当前 shopListViewItem 对象:"+shopInfos.get(position));            return shopInfos.get(position);        }        //得到 item 的 id        @Override        public long getItemId(int position) {            Log.i(Tag, "当前 shopListViewItem 的 id:"+position);            return position;        }        //得到 item 的 View 视图        /*@Override        public View getView(int position, View convertView, ViewGroup parent) {            //将list_item.xml文件找出来并转换为View对象            View view = View.inflate(MainActivity.this,R.layout.list_item,null);            TextView mTextView = (TextView) view.findViewById(R.id.item_tv);            mTextView.setText(names[position]);            ImageView imageView = (ImageView) view.findViewById(R.id.item_image);            imageView.setBackgroundResource(icons[position]);            return view;        }*/        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder holder;            //将 shop_list_item.xml 文件找出来并转换为 View 对象            if (convertView == null) {                convertView = LayoutInflater.from(                        getApplicationContext()).inflate(R.layout.shop_list_item, parent, false);                holder = new ViewHolder();                holder.mTextView1 = (TextView) convertView.findViewById(R.id.item_tv_brand_name);                holder.mTextView2 = (TextView) convertView.findViewById(R.id.item_tv_brand_sales);                holder.mTextView3 = (TextView) convertView.findViewById(R.id.item_tv_start_delivery_cost);                holder.mTextView4 = (TextView) convertView.findViewById(R.id.item_tv_delivery_cost);                holder.mTextView5 = (TextView) convertView.findViewById(R.id.item_tv_brand_evaluation);                holder.mTextView6 = (TextView) convertView.findViewById(R.id.item_tv_delivery_time);                holder.imageView = (ImageView) convertView.findViewById(R.id.item_image_brand);                convertView.setTag(holder);            } else {                holder = (ViewHolder) convertView.getTag();            }            holder.mTextView1.setText(shopInfos.get(position).getBrandName());            holder.mTextView2.setText(shopInfos.get(position).getBrandSales());            holder.mTextView3.setText("起送¥"+shopInfos.get(position).getStartDeliveryCost());            holder.mTextView4.setText("|配送¥"+shopInfos.get(position).getDeliveryCost());            holder.mTextView5.setText(shopInfos.get(position).getBrandEvaluation());            holder.mTextView6.setText("配送约"+shopInfos.get(position).getDeliveryTime()+"分钟");            holder.imageView.setBackgroundResource(shopInfos.get(position).getBrandId());            return convertView;        }        class ViewHolder {            TextView mTextView1;            TextView mTextView2;            TextView mTextView3;            TextView mTextView4;            TextView mTextView5;            TextView mTextView6;            ImageView imageView;        }    }

                3)条目点击事件监听函数onItemClick,因为要判断是哪个店铺被点击从而进入对应的店铺查看其所有商品,并且在onCreate函数中已经设置了监听事件,后面的在某个店铺点击某个商品是类似的实现,只需要在给每个条目里面的按钮设置点击事件就可以了,具体不给出,但是会把所有资源上传,需要的自行下载

    @Override    public void onItemClick(AdapterView adapterView, View view, int position, long id) {        Toast.makeText(MainActivity.this,"第"+position+"个 shopListViewItem 被点击了,"+"id:"+id,Toast.LENGTH_SHORT).show();        Log.i(Tag,"当前被点击的 shopListViewItem 对象:"+shopInfos.get(position));        //创建Intent对象,TakeawayActivity        Intent intent = new Intent(this, TakeawayActivity.class);        intent.putExtra("shopInfo", String.valueOf(shopInfos.get(position)));        intent.putExtra("userInfo", userInfo);        startActivityForResult(intent,1);        intent=null;        Log.i(Tag,"clearIntentInMainActivityOnItemClick");    }

4 实验结果与分析

所有已实现的功能展示均在这个视频里面

Android课设-网上商城/外卖小助手

5 代码

5.1 Android代码

        安卓-Android Studio-仿美团外卖Android全部资源

5.2 Idea服务器代码

        服务器-Spring Boot-仿美团外卖服务器全部资源

上一篇:【Servlet】——Servlet API 详解

下一篇:怎么输入服务器端口码?