网络资源模板--基于Android Studio 实现的食谱助手App

发布于:2025-06-30 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

一、项目简介

二、项目演示

三、部设计详情(部分)

登录页面

菜谱页面

食物页

我的页面

四、项目源码 


一、项目简介

根据软件设计的需求进行总结,确定本软件各种功能的实现,并通过以下几个模块来满足该软件基本功能,其中功能模块的分别为:

用户注册:新用户输入用户名和密码进行账号的注册。

用户登录:已注册的用户输入用户名和密码进行登录。

食物:查看不同食物的科普和不宜同食的食物。

菜谱:对菜谱进进行查看、收藏、取消收藏。

我的菜单:用户可以添加属于自己的菜单,并进行菜单的修改和删除。

我的收藏:用户可以查看收藏的菜谱,并可对菜谱取消收藏

分享应用:用户可以将软件进行分享

关于:了解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();
    }
}

四、项目源码 

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


网站公告

今日签到

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