目录
一、测试环境说明
电脑环境
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);
}
}
五、项目源码
👇👇👇👇👇快捷方式👇👇👇👇👇