目录
一、项目简介
根据软件设计的需求进行总结,确定本软件各种功能的实现,并通过以下几个模块来满足该软件基本功能,其中功能模块的分别为:
用户注册:新用户输入用户名和密码进行账号的注册。
用户登录:已注册的用户输入用户名和密码进行登录。
食物:查看不同食物的科普和不宜同食的食物。
菜谱:对菜谱进进行查看、收藏、取消收藏。
我的菜单:用户可以添加属于自己的菜单,并进行菜单的修改和删除。
我的收藏:用户可以查看收藏的菜谱,并可对菜谱取消收藏
分享应用:用户可以将软件进行分享
关于:了解app版本,查看app的介绍
二、项目演示
网络资源模板--基于Android studio 食谱手册App
三、部设计详情(部分)
登录页面
1. 当前页面的结构
该登录页面采用经典的FrameLayout嵌套LinearLayout布局结构,整体分为背景层和内容层。
背景层使用ImageView展示全屏背景图,内容层采用垂直排列的LinearLayout,包含应用标题、用户名输入框、密码输入框、记住密码复选框、登录按钮和注册入口文本。
各UI元素间距合理,通过margin和padding控制视觉效果,整体布局层次分明,重点突出登录功能区域。
2. 当前页面用到的技术
页面融合了多种Android核心技术:使用SharedPreferences实现记住密码功能;
通过SQLite数据库完成用户认证;采用Activity跳转实现页面导航;利用Toast提供操作反馈。
界面方面运用了FrameLayout的层叠特性、LinearLayout的线性排列、EditText的输入控制以及CheckBox的状态保存。
整体采用MVC模式分离业务逻辑与界面展示。
3. 当前页面的详细介绍
这是一个标准的用户登录界面,主要功能包括:用户输入验证、密码记忆、登录状态跳转和注册入口。
背景采用美食图片营造应用氛围,输入框添加自定义边框增强视觉效果。
功能逻辑上实现了自动填充记住的账号密码,登录成功后跳转主页并清除或保存凭证,失败时提示错误信息。
注册文本提供次级入口,形成完整的账号体系入口闭环。
package com.example.foodguide.activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.foodguide.R;
import com.example.foodguide.db.SqliteResult;
import com.example.foodguide.db.TableUser;
import com.example.foodguide.entity.User;
import com.gzone.university.utils.CurrentUserUtils;
public class LoginActivity extends AppCompatActivity {
private static final String PREF_NAME = "login_pref";
private static final String KEY_USERNAME = "username";
private static final String KEY_PASSWORD = "password";
private static final String KEY_REMEMBER = "remember";
private EditText etUsername;
private EditText etPassword;
private Button btnLogin;
private TextView tvRegister;
private CheckBox cbRememberPwd;
private SharedPreferences sp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// 绑定控件
bindView();
// 初始化视图
initView();
// 检查是否有保存的登录信息
checkSavedCredentials();
}
private void bindView() {
etUsername = findViewById(R.id.et_username);
etPassword = findViewById(R.id.et_password);
btnLogin = findViewById(R.id.btn_login);
tvRegister = findViewById(R.id.tv_register);
cbRememberPwd = findViewById(R.id.cb_remember_pwd);
sp = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
}
private void initView() {
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
attemptLogin();
}
});
tvRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openRegisterActivity();
}
});
}
private void checkSavedCredentials() {
boolean isRemember = sp.getBoolean(KEY_REMEMBER, false);
if (isRemember) {
String savedUsername = sp.getString(KEY_USERNAME, "");
String savedPassword = sp.getString(KEY_PASSWORD, "");
etUsername.setText(savedUsername);
etPassword.setText(savedPassword);
cbRememberPwd.setChecked(true);
}
}
private void attemptLogin() {
// 获取输入值
String username = etUsername.getText().toString().trim();
String password = etPassword.getText().toString().trim();
// 执行登录
SqliteResult<User> result = TableUser.login(username, password);
if (result.isSuccess()) {
// 保存登录信息
CurrentUserUtils.setCurrentUser(result.getData());
// 登录成功
loginSuccess();
} else {
// 登录失败
Toast.makeText(this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
}
}
private void loginSuccess() {
// 处理记住密码
SharedPreferences.Editor editor = sp.edit();
if (cbRememberPwd.isChecked()) {
editor.putString(KEY_USERNAME, etUsername.getText().toString().trim());
editor.putString(KEY_PASSWORD, etPassword.getText().toString().trim());
editor.putBoolean(KEY_REMEMBER, true);
} else {
editor.clear();
}
editor.apply();
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
// 跳转到主页
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
public void openRegisterActivity() {
Intent intent = new Intent(this, RegisterActivity.class);
startActivity(intent);
}
}
菜谱页面
1. 当前页面的结构
该页面采用CoordinatorLayout作为根布局,内部嵌套垂直LinearLayout实现整体页面结构。
顶部是160dp高度的轮播图区域,使用RelativeLayout包裹ViewPager2和自定义圆形指示器。
主体部分采用SwipeRefreshLayout包裹RecyclerView,实现下拉刷新功能。
轮播图与列表区域通过线性布局顺序排列,指示器绝对定位在轮播图底部居中位置,整体布局层次清晰,视觉重点突出。
2. 当前页面用到的技术
页面集成了多种高级组件:ViewPager2实现轮播图效果;自定义CircleIndicatorView提供轮播指示;
RecyclerView以网格布局展示菜品;SwipeRefreshLayout支持下拉刷新。通过Handler实现轮播自动播放,利用Collections.shuffle实现数据随机排序。
页面生命周期管理确保轮播定时器的正确启停,Intent传递Parcelable对象实现页面跳转数据传递。
3. 当前页面的详细介绍
这是一个功能丰富的菜单展示页面,主要包含轮播图和菜品网格两大核心模块。
轮播图自动循环播放多张美食图片,配有圆形分页指示器。菜品区域采用两列网格布局,支持下拉刷新重新随机排序。
点击任意菜品跳转至详情页,传递完整的菜品数据对象。
页面通过精确的生命周期管理优化性能,在不可见时停止轮播节省资源,整体交互流畅自然。
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 轮播图布局 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="160dp">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_banner"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.foodguide.view.CircleIndicatorView
android:id="@+id/circle_indicator"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp" />
</RelativeLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/srl_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
食物页
1. 当前页面的结构
该页面采用双层线性布局结构,顶部是固定高度的标题栏,使用FrameLayout包裹TextView显示"食物"标题。
主体部分采用SwipeRefreshLayout包裹RecyclerView,实现下拉刷新功能。
RecyclerView设置8dp的内边距使内容不会紧贴边缘,同时通过clipToPadding属性确保滚动时内容可以延伸到padding区域。
整体布局简洁高效,标题栏与内容区域比例协调。
2. 当前页面用到的技术
页面运用了多种现代化Android组件:SwipeRefreshLayout实现下拉刷新交互;
RecyclerView展示高效列表;自定义Adapter处理数据绑定和点击事件;Fragment作为页面容器。
数据方面采用静态数据类FoodData提供数据源,通过Collections.shuffle实现随机排序效果。
页面跳转使用Intent传递Parcelable对象,整体架构符合单一职责原则。
3. 当前页面的详细介绍
这是一个食物列表展示页面,主要功能包括:随机展示食物列表、下拉刷新重新排序、点击跳转详情页。
标题栏采用品牌主色强化视觉识别,列表区域支持手势刷新交互。
业务逻辑上实现了数据获取、随机排序、列表渲染和点击跳转的完整链路。
下拉刷新时会重新打乱数据顺序,提供新鲜感。点击任意食物项可查看详情,传递完整食物对象保证数据一致性。
package com.example.foodguide.fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.example.foodguide.R;
import com.example.foodguide.activity.FoodDetailActivity;
import com.example.foodguide.adapter.FoodAdapter;
import com.example.foodguide.data.FoodData;
import com.example.foodguide.entity.Food;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class FoodFragment extends Fragment {
private RecyclerView rvFood;
private SwipeRefreshLayout srlFood;
private FoodAdapter adapter;
@Nullable
@Override
public View onCreateView( LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_food, container, false);
initView(view);
initData();
return view;
}
private void initView(View view) {
rvFood = view.findViewById(R.id.rv_food);
srlFood = view.findViewById(R.id.srl_food);
// 配置SwipeRefreshLayout
srlFood.setColorSchemeResources(R.color.main);
srlFood.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshFoodData();
}
});
// 创建适配器
adapter = new FoodAdapter(rvFood);
// 设置点击事件
adapter.setOnItemClickListener(new FoodAdapter.OnItemClickListener() {
@Override
public void onItemClick(Food food) {
// 跳转到食物详情页
Intent intent = new Intent(requireContext(), FoodDetailActivity.class);
intent.putExtra(FoodDetailActivity.EXTRA_FOOD, food);
startActivity(intent);
}
});
}
private void initData() {
// 从FoodData获取食物列表数据
List<Food> foodList = FoodData.getFoodList();
Collections.shuffle(foodList);
adapter.updateData(foodList);
}
private void refreshFoodData() {
// 获取新的随机排序食物列表
List<Food> foodList = new ArrayList<>(FoodData.getFoodList());
Collections.shuffle(foodList);
// 更新适配器数据
adapter.updateData(foodList);
// 隐藏刷新进度条
srlFood.setRefreshing(false);
}
}
我的页面
1. 当前页面的结构
该页面采用垂直嵌套结构,顶部是用户信息卡片,展示头像、用户名和欢迎语。
中间是功能菜单区,包含"我的菜单"、"我的收藏"、"分享应用"和"关于"四个可点击选项,每个选项由图标、文字和箭头组成,用分割线隔开。
底部是退出登录按钮。整体采用卡片式设计,通过边距和背景色区分不同区块,布局层次清晰,重点突出用户信息和主要功能入口。
2. 当前页面用到的技术
页面使用NestedScrollView实现可滚动布局,LinearLayout构建垂直排列的UI结构。
通过系统分享Intent实现应用分享功能,AlertDialog提供退出确认交互。
利用CurrentUserUtils管理用户登录状态,Activity跳转实现页面导航。
界面设计采用Material风格,包括卡片背景、点击波纹效果和统一的图标风格,整体保持视觉一致性。
3. 当前页面的详细介绍
这是个人中心页面,核心功能包括展示用户信息、提供功能入口和账户管理。
用户信息区实时显示当前登录账号,四个功能入口分别跳转对应页面,分享功能调用系统原生分享组件。
退出登录采用二次确认机制,确保操作安全性。
页面设计注重用户体验,所有可点击区域都有视觉反馈,布局间距合理,色彩搭配符合应用整体风格,是典型的用户个人中心模块实现。
package com.example.foodguide.fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.example.foodguide.R;
import com.example.foodguide.activity.AboutActivity;
import com.example.foodguide.activity.FavoriteMenuActivity;
import com.example.foodguide.activity.LoginActivity;
import com.example.foodguide.activity.MyMenuActivity;
import com.example.foodguide.entity.User;
import com.gzone.university.utils.CurrentUserUtils;
import org.jetbrains.annotations.Nullable;
public class MineFragment extends Fragment {
private TextView tvUsername;
private Button btnLogout;
private LinearLayout llMyMenus, llMyFavorites, llShare, llAbout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_mine, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
bindView(view);
initView();
}
private void bindView(View view) {
// 初始化视图
tvUsername = view.findViewById(R.id.tv_username);
btnLogout = view.findViewById(R.id.btn_logout);
llMyMenus = view.findViewById(R.id.ll_my_menus);
llMyFavorites = view.findViewById(R.id.ll_my_favorites);
llShare = view.findViewById(R.id.ll_share);
llAbout = view.findViewById(R.id.ll_about);
}
private void initView() {
// 加载用户信息
loadUserInfo();
// 设置点击事件
btnLogout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showLogoutConfirmDialog();
}
});
llMyMenus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到我的菜单页面
Intent intent = new Intent(getActivity(), MyMenuActivity.class);
startActivity(intent);
}
});
llMyFavorites.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到收藏菜谱页面
Intent intent = new Intent(getActivity(), FavoriteMenuActivity.class);
startActivity(intent);
}
});
llShare.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//调用系统自带的分享功能
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
String msg = "保持健康的饮食至关重要。通过了解营养和热量,选择合适食物,提升健康。想了解更多?快来下载食谱手册App吧!";
intent.putExtra(Intent.EXTRA_TEXT, msg);
startActivity(Intent.createChooser(intent, "食谱手册分享"));
}
});
llAbout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到关于页面
Intent intent = new Intent(getActivity(), AboutActivity.class);
startActivity(intent);
}
});
}
private void loadUserInfo() {
User currentUser = CurrentUserUtils.getCurrentUser(User.class);
tvUsername.setText(currentUser.getUsername());
}
private void showLogoutConfirmDialog() {
new AlertDialog.Builder(getActivity())
.setTitle("退出登录")
.setMessage("确定要退出登录吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
logout();
}
})
.setNegativeButton("取消", null)
.show();
}
private void logout() {
// 清除登录状态
CurrentUserUtils.clear();
// 跳转到登录页面
Intent intent = new Intent(getActivity(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
getActivity().finish();
}
}
四、项目源码
👇👇👇👇👇快捷方式👇👇👇👇👇