网络资源模板--基于Android Studio 实现的线上点餐系统

发布于:2025-07-26 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

一、测试环境说明

二、项目简介

三、项目演示

四、部设计详情(部分)

注册页面

首页

五、项目源码 


一、测试环境说明

电脑环境

Windows 11

编写语言

JAVA

开发软件

Android Studio  (2020)

开发软件只要大于等于测试版本即可(近几年官网直接下载也可以),若是版本低于测试版本请自行测试。项目需要根据你的软件自行适配

二、项目简介

该项目简介来自网络,具体内容需要自行测试

本系统基于Android Studio开发,采用Java语言编写,使用SQLite关系型数据库存储核心数据。

配合SharedPreferences实现轻量级配置存储,主要使用RecyclerView展示列表数据。

并配合自定义控件(如PayPwdEditText密码输入框),整体采用MVC架构模式实现业务逻辑与界面分离。

三、项目演示

网络资源模板--基于Android studio 线上点餐系统

四、部设计详情(部分)

注册页面

1. 页面结构分析

该页面采用垂直线性布局,顶部包含标题栏,中部是圆形头像展示区,下部采用TabLayout与ViewPager组合实现多标签页切换功能。

整体结构清晰分为三个层次:标题区、用户形象展示区和功能操作区。ViewPager内嵌两个子页面,分别处理用户注册和密码找回功能,通过滑动或点击标签可自由切换。

这种分层设计既保持了界面整洁,又确保了功能的可扩展性。

2. 核心技术应用

页面运用了Android Material Design组件库,特别是TabLayout与ViewPager的联动技术实现标签页切换。

圆形头像通过第三方CircleImageView库实现,状态栏透明化处理提升了视觉沉浸感。数据持久化方面结合了SQLite数据库操作和SharedPreferences轻量存储,表单验证逻辑包含手机号格式校验、密码强度检测等业务规则,通过适配器模式动态管理不同功能的Fragment视图。

3. 功能模块详解

注册模块包含用户名、密码、性别选择和手机号输入,通过严格的正则校验确保数据合规性,采用对话框实现性别选择交互。

密码找回模块需验证绑定手机号,并进行双重密码一致性检查,通过状态码机制处理各类业务异常。

两个模块共享同一套错误提示系统,采用自定义Toast样式统一展示校验结果,整体流程符合典型用户账户系统的安全设计规范。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <include layout="@layout/titlebar"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center">
        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:src="@drawable/icon_online_bg"
            />

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="50dp"
            android:layout_height="30dp"
            android:src="@drawable/user_bule"
            android:text="账 号:"/>
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:counterEnabled="true"
            app:counterMaxLength="12"
            app:errorEnabled="true"
            app:errorTextAppearance="@style/Error"
>
        <EditText
            android:id="@+id/username"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="用户名"
            android:paddingLeft="10dp"
            android:singleLine="true"
            android:textColor="#ff000000"
            android:textSize="15sp"

            />
        </com.google.android.material.textfield.TextInputLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center"
        android:gravity="center">

        <ImageView
            android:id="@+id/TipsPassWord"
            android:layout_width="50dp"
            android:layout_height="30dp"
            android:src="@drawable/icon_password_1"/>
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:counterEnabled="true"
            app:counterMaxLength="12"
            app:errorEnabled="true"
            app:errorTextAppearance="@style/Error"
            app:passwordToggleEnabled="true">
        <EditText
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginTop="10dp"
            android:layout_toRightOf="@+id/TipsPassWord"
            android:hint="密   码"
            android:paddingLeft="10dp"
            android:password="true"
            android:textColor="#ff000000"
            android:textSize="15sp" />

        </com.google.android.material.textfield.TextInputLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginLeft="20dp"
        android:gravity="left">
        <CheckBox
                android:id="@+id/AgreementStatus"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="false"
                />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="已阅读并同意“线上点餐系统”《服务协议》和《隐私政策》"
            android:textSize="10sp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_marginTop="60dp">
        <Button
            android:id="@+id/login"
            android:layout_width="250dp"
            android:layout_height="40dp"
            android:background="@drawable/btn_blue"
            android:text="进入线上点餐系统"
            android:textColor="#ffffff"
            android:textSize="15sp"/>
    </LinearLayout>
</LinearLayout>


首页

1. 页面结构分析

该页面采用垂直线性布局,顶部包含标题栏,中部是商品统计信息和清空按钮,底部为商品列表展示区和操作按钮区。

商品列表使用RecyclerView实现滚动浏览,支持动态增减商品数量。底部操作区包含返回首页和立即支付两个功能按钮,整体布局层次分明。

页面通过权重分配确保商品列表区域占据主要空间,统计信息与操作按钮固定显示,符合电商购物车的典型设计范式。

2. 核心技术应用

采用RecyclerView配合BaseQuickAdapter实现高性能商品列表渲染,支持子项局部刷新。

通过SQLite数据库管理商品数据,结合SharedPreferences存储订单总价。数量增减功能采用事件监听机制,实时计算总价并更新UI。

状态栏透明化处理增强视觉体验,按钮使用自定义选择器实现点击反馈。数据绑定采用面向对象方式,将数据库查询结果映射到实体类再传递给适配器。

3. 功能模块详解

商品统计区动态显示商品总件数和实时总价,清空按钮可一键移除所有商品。列表项包含增减数量功能按钮,通过适配器内部方法实现价格联动计算。

支付流程采用页面跳转传参设计,总价数据通过轻量存储传递至支付页面。返回按钮保留历史记录栈管理,确保导航逻辑符合用户预期。

整个购物车模块实现CRUD完整操作闭环,数据变化实时响应无延迟。

package com.example.OrderOnline.Activity;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.example.OrderOnline.R;
import com.example.OrderOnline.SQLite.Dao;
import com.example.OrderOnline.adapter.goodsListAdapter;
import com.example.OrderOnline.tool.GoodsList;
import com.example.OrderOnline.util.KillProcess;
import com.example.OrderOnline.util.SP;

import java.util.ArrayList;
import java.util.List;

public class GoodsListActivity extends AppCompatActivity {
    private RecyclerView GoodsListRecyclerView;
    private com.example.OrderOnline.adapter.goodsListAdapter goodsListAdapter;
    private List<GoodsList> goodsLists = new ArrayList<>();
    private List<GoodsList> dataList = new ArrayList<>();
    private GoodsList goodsList;
    private Dao dao;
    private Context context = null;
    private double totalPrice = 0;
    private TextView goodsTotalNumber, goodsTotalPrice, other;
    private Button goodsAllClear;
    private KillProcess killProcess;
    private SP sp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= 21) {
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
        setContentView(R.layout.activity_goods_list);
        InitView();
        InitRecycler();
        InitData();
        Listener();
        InitBarData();
        goodsAllClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                goodsListAdapter.removeAllItem(dataList);
                goodsTotalNumber.setText(0 + "");
                goodsTotalPrice.setText(0 + "");
            }
        });
    }

    private void InitView() {
        GoodsListRecyclerView = findViewById(R.id.GoodsListRecyclerView);
        goodsTotalNumber = findViewById(R.id.goodsTotalNumber);
        goodsTotalPrice = findViewById(R.id.goodsTotalPrice);
        goodsAllClear = findViewById(R.id.clearAllGoods);
        other = findViewById(R.id.exchangeFunc);
        other.setVisibility(View.GONE);
        if (context == null) {
            context = GoodsListActivity.this;
        }
        dao = new Dao(context);
        killProcess = KillProcess.getInstance();
        killProcess.addActivity(GoodsListActivity.this);
        sp = SP.getInstance();
    }

    private void InitRecycler() {
        LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
        GoodsListRecyclerView.setLayoutManager(manager);
        goodsListAdapter = new goodsListAdapter(context, R.layout.goods_item, dataList);
        GoodsListRecyclerView.setAdapter(goodsListAdapter);
    }

    private void Listener() {
        goodsListAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                int num = dataList.get(position).getNumber();
                double price = dataList.get(position).getPrice();
                switch (view.getId()) {
                    case R.id.goodsAdd:
                        goodsListAdapter.addPrice(dataList, price, position, num);
                        InitBarData();
                        //Toast.makeText( GoodsListActivity.this,"Add"+num,Toast.LENGTH_SHORT ).show();
                        break;
                    case R.id.goodsSub:
                        goodsListAdapter.subPrice(dataList, price, position, num);
                        InitBarData();
                        //Toast.makeText( GoodsListActivity.this,"Sub"+num,Toast.LENGTH_SHORT ).show();
                        break;
                }
            }
        });
    }

    private void InitData() {
        goodsLists = dao.QueryAll();
        for (int i = 0; i < goodsLists.size(); i++) {
            goodsList = new GoodsList(goodsLists.get(i).getUserName(), goodsLists.get(i).getPassWord(), goodsLists.get(i).getImg(), goodsLists.get(i).getName(), goodsLists.get(i).getPrice(), goodsLists.get(i).getNumber(), goodsLists.get(i).getSub(), goodsLists.get(i).getAdd());
            dataList.add(goodsList);
        }
    }

    private void InitBarData() {
        goodsTotalNumber.setText(goodsListAdapter.TotalNumber(dataList) + "");
        goodsTotalPrice.setText(FunctionActivity.doubleToString(goodsListAdapter.TotalPrice(dataList)));
    }

    public void Exit(View view) {
        ReturnActivity(FunctionActivity.class);
    }

    private void ReturnActivity(Class Activity) {
        startActivity(new Intent(context, Activity));
    }

    public void ReturnFirstPage(View view) {
        ReturnActivity(FunctionActivity.class);
    }

    public void ReturnPayment(View view) {
        String monry = goodsTotalPrice.getText().toString();
        sp.PutData(GoodsListActivity.this, "TotalPrice", monry);
        ReturnActivity(PaymentActivity.class);

    }
}

五、项目源码 

👇👇👇👇👇快捷方式👇👇👇👇👇


网站公告

今日签到

点亮在社区的每一天
去签到