智能菜谱课程设计报告
Posted pengdongya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了智能菜谱课程设计报告相关的知识,希望对你有一定的参考价值。
一.系统需求分析 3
1.概述
随着智能手机的普及,基于android平台的应用软件需求也越来越多。针对传统订餐模式中餐馆工作人员重复劳动量大、消费者在不熟悉地区难以寻找适合自己的餐馆、必须要进入到餐馆内才可以浏览菜单开始点餐以及物理菜单不能及时更新更不能反映菜品的评价等缺点,提出基于Android平台的智能菜谱系统的设计和实现解决方案。阐述了系统的设计思想、开发模型、主要功能模块以及关键技术的设计与实现。
2.需求用例图
3.用例分析
(1)用例名称:今日推荐
说明:每进一次首页都会推荐
不同的菜品,可自行选择
(2)用例名称:分类查询
说明:有九种类型的菜,每种类型
的菜又可以分很多菜品,可
任意选择进行查询
(3)用例名称:添加收藏
说明:用户可把喜欢的菜添加到收藏
(4)用例名称:删除收藏
说明:用户可把不喜欢的菜从收藏中
删除
(5)用例名称:上传我的菜品
说明:可以把自己喜欢或会做的菜
上传,与他人进行分享
二、 系统设计
1.系统功能
2.核心模块时序图
3.核心模块类图
三、 系统数据库设计
由于本系统是对广大用户所使用的,所以要充分考虑用户的需求。本系统采用了SQLite数据库设计,占用资源低,处理速度快。以表格的形式列出每一个数据库表的表结构,即字段名、类型、长度、小数位数、是否主键、索引、是否允许为空、说明等。并介绍表与表之间的逻辑关系。
Information 表结构
字段名 |
数据类型 |
长度 |
主键 |
索引 |
外键 |
可空 |
说明 |
id |
int |
20 |
是 |
|
否 |
否 |
菜品id |
name |
String |
20 |
否 |
|
否 |
否 |
菜品名字 |
method |
String |
Unknow |
否 |
|
否 |
否 |
烹饪方法 |
material |
String |
30 |
否 |
|
否 |
否 |
材料 |
is_favor |
int |
30 |
否 |
|
否 |
是 |
喜欢的菜品 |
type_id |
int |
20 |
否 |
|
否 |
否 |
种类id |
四、系统测试
本次实习所用的开发环境为:
开发所涉及的应用:UI设计,activity组件的应用,file存储
服务器:Android studio
数据库:SQLite
开发工具:Android studio,SQLite
界面制作:UI
1.项目测试
1、测试软件作品能否在模拟器和手机上正常运行
2、测试数据库能否顺利连接
3、测试软件作品各个功能能否正常进行:
3.1、测试首页登录功能是否能正常使用
3.2、测试分类查询功能是否能正常使用
3.3、测试收藏功能是否能正常使用
3.4、测试上传菜品功能是否能正常使用
2. 测试结果
不同界面运行图如下:
上图测试了在模拟器和手机中各个界面的运行图,登录界面,分类界面,收藏界面和上传菜品界面的样式都是保持完整的,同时功能也是健全的。测试过程中遇到了很多问题,比如说页面的跳转实现不了,好友推荐的功能实现不了,存在问题,点击后直接跳转到登录界面。还有一些其他错误,经过调试和修改后都一一成功实现了。
五. 系统实现
1. 登录界面
进入登录界面,输入手机号和验证码,登录成功后进入首页可以看到今日推荐的菜品
部分关键代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/colorPrimaryDark"
tools:context=".LoginActivity">
<ImageView
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:background="@drawable/a2"
android:layout_width="150dp"
android:layout_height="180dp" />
<LinearLayout
android:layout_marginLeft="30dp"
android:layout_centerInParent="true"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/lin"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:text="手机号:"
android:textStyle="bold"
android:textColor="@color/cookbook_white"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:hint="请输入手机号"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_below="@+id/lin"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:text="验证码:"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="@color/cookbook_white"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:hint="请输入验证码"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/btn"
android:text="登录"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:textStyle="bold"
android:textSize="25sp"
android:textColor="@color/cookbook_white"
android:background="@color/div_white"
android:layout_width="100dp"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:text="@string/text_recommend"
android:textColor="@color/holo_orange_light"
android:textSize="35sp"
android:textStyle="bold"
/>
<android.support.v4.view.ViewPager
android:id="@+id/pager_cook"
android:layout_width="250dp"
android:layout_height="300dp"
android:layout_gravity="center_horizontal"
android:padding="5dp" />
<TextView
android:id="@+id/tv_index_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:text="香酥鸡"
android:textColor="@color/holo_blue_dark"
android:textSize="25sp"
android:textStyle="bold"
/>
<LinearLayout
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/iv_first_point"
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_weight="1"
android:contentDescription="@string/image_indicator"
android:src="@drawable/index_point_state"
/>
<ImageView
android:id="@+id/iv_second_point"
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_weight="1"
android:contentDescription="@string/image_indicator"
android:src="@drawable/index_point_state"
/>
<ImageView
android:id="@+id/iv_third_point"
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_weight="1"
android:contentDescription="@string/image_indicator"
android:src="@drawable/index_point_state"
/>
</LinearLayout>
</LinearLayout>
package com.example.lm.cook;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
startActivity(new Intent(LoginActivity.this,SplashActivity.class));
}
});
}
}
2.分类查询界面
进入分类查询界面,可以任意查询各类菜品,也可以通过右上角搜索工具对喜欢的菜直接进行搜索查询,就可以不用一一查询菜品了。
部分关键代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_item_search"
android:icon="@mipmap/ic_menu_search"
android:title="@string/search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="ifRoom"
/>
</menu>
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
MenuItem item = menu.findItem(R.id.menu_item_search);
mSearchView = (SearchView) item.getActionView();
if (mSearchView != null) {
mSearchView.setInputType(InputType.TYPE_CLASS_TEXT);
mSearchView.setSubmitButtonEnabled(false);
mSearchView.setQueryHint(getString(R.string.search_hint));
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRadioGroup.setVisibility(View.GONE);
mActionBar.setDisplayHomeAsUpEnabled(true);
mCookDao = new CookDao(MainActivity.this);
FragmentTransaction transaction = mFragmentManager.beginTransaction();
hideAllFgt(transaction);
if (mSearchFgt == null) {
mSearchFgt = new SearchFgt();
transaction.add(R.id.main_content, mSearchFgt);
} else {
transaction.show(mSearchFgt);
}
transaction.commit();
}
});
}
return true;
}
3. 收藏界面
对各种菜品进行查询后,可以把自己喜欢的菜添加到收藏里,方便以后查找,也可以删除收藏里的菜品,进行清理。
部分关键代码如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="@+id/detail_content"
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">
</FrameLayout>
package com.example.lm.cook;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.lm.cook.dao.CookDao;
import com.example.lm.cook.fragment.DetailFgt;
import com.example.lm.cook.pojo.Cook;
import com.example.lm.cook.utils.Const;
public class DetailActivity extends AppCompatActivity {
private boolean isFavorite;
private int mCookId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
mCookId = getIntent().getIntExtra(Const.COOK_KEY, 0);
CookDao cookDao = new CookDao(this);
Cook cook = cookDao.getCook(mCookId);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
setTitle(cook != null ? cook.getName() : null);
isFavorite = cook != null && cook.isFavorite();
if (savedInstanceState == null) {
DetailFgt detailFgt = DetailFgt.newInstance(cook);
getSupportFragmentManager().beginTransaction().add(R.id.detail_content, detailFgt).commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_favor, menu);
if (isFavorite) {
menu.getItem(0).setIcon(R.mipmap.favorite);
menu.getItem(0).setTitle(getString(R.string.cancel_favor));
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
} else if (item.getItemId() == R.id.menu_item_favor) {
CookDao cookDao = new CookDao(this);
if (cookDao.doFavor(mCookId, isFavorite)) {
if (isFavorite) {
item.setIcon(R.mipmap.not_favorite);
item.setTitle(R.string.cancel_favor);
Toast.makeText(this, R.string.cancel_favor, Toast.LENGTH_SHORT).show();
} else {
item.setIcon(R.mipmap.favorite);
item.setTitle(getString(R.string.favor));
Toast.makeText(this, R.string.favor_succeed, Toast.LENGTH_SHORT).show();
}
isFavorite = !isFavorite;
}
}
return true;
}
}
4.更多界面
进入更多界面后,有上传菜单、推荐好友和检查更新三个选项,用户可以上传自己喜欢的菜,与他人进行分享,同时也给系统提供参照,完善菜品种类。
部分关键代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_more_help"
style="@style/more_fgt_style"
android:text="@string/more_help"
/>
<TextView
android:layout_marginTop="20dp"
android:id="@+id/tv_more_recommend"
style="@style/more_fgt_style"
android:text="@string/more_recommend"
/>
<TextView
android:layout_marginTop="20dp"
android:id="@+id/tv_more_update"
style="@style/more_fgt_style"
android:text="@string/more_check_update"
/>
</LinearLayout>
package com.example.lm.cook.fragment;
import...
public class MoreFgt extends Fragment implements View.OnClickListener {
private Context mContext;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_more, container, false);
view.findViewById(R.id.tv_more_update).setOnClickListener(this);
view.findViewById(R.id.tv_more_recommend).setOnClickListener(this);
view.findViewById(R.id.tv_more_help).setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_more_help:
//上传菜谱
startActivity(new Intent(getContext(),AddActivity.class));
break;
case R.id.tv_more_update:
final ProgressDialog dialog = new ProgressDialog(mContext);
dialog.setTitle(mContext.getString(R.string.text_checking));
dialog.setMessage(mContext.getString(R.string.text_wait));
dialog.setCancelable(false);
dialog.setIndeterminate(true);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Toast.makeText(mContext, R.string.text_new_version, Toast.LENGTH_SHORT).show();
}
});
dialog.show();
TimerTask task = new TimerTask() {
@Override
public void run() {
dialog.cancel();
}
};
Timer timer = new Timer();
timer.schedule(task, Const.DELAY_TIME);
break;
case R.id.tv_more_recommend:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_SEND);
File file = new File(mContext.getFilesDir() + File.separator + "share.png");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.putExtra(Intent.EXTRA_TEXT, "推荐给你一个好玩的的应用--家常菜菜谱");
startActivity(intent);
break;
}
}
}
其他部分关键代码:
package com.example.lm.cook.adapter;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public abstract class CommonAdapter<T> extends BaseAdapter {
public List<T> mData;
private int mLayoutRes; //布局id
public CommonAdapter() {
}
public CommonAdapter(List<T> mData, int mLayoutRes) {
this.mData = mData;
this.mLayoutRes = mLayoutRes;
}
@Override
public int getCount() {
return mData != null ? mData.size() : 0;
}
@Override
public T getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.bind(parent.getContext(), convertView, parent, mLayoutRes
, position);
bindView(holder, getItem(position));
return holder.getItemView();
}
public abstract void bindView(ViewHolder holder, T obj);
public void setData(List<T> data) {
mData = data;
notifyDataSetChanged();
}
//添加一个元素
public void add(T data) {
if (mData == null) {
mData = new ArrayList<>();
}
mData.add(data);
notifyDataSetChanged();
}
//往特定位置,添加一个元素
public void add(int position, T data) {
if (mData == null) {
mData = new ArrayList<>();
}
mData.add(position, data);
notifyDataSetChanged();
}
public void remove(T data) {
if (mData != null) {
mData.remove(data);
}
notifyDataSetChanged();
}
public void remove(int position) {
if (mData != null) {
mData.remove(position);
}
notifyDataSetChanged();
}
public void clear() {
if (mData != null) {
mData.clear();
}
notifyDataSetChanged();
}
public static class ViewHolder {
private SparseArray<View> mViews; //存储ListView 的 item中的View
private View item; //存放convertView
private int position; //游标
private Context context; //Context上下文
//构造方法,完成相关初始化
private ViewHolder(Context context, ViewGroup parent, int layoutRes) {
mViews = new SparseArray<>();
this.context = context;
View convertView = LayoutInflater.from(context).inflate(layoutRes, parent, false);
convertView.setTag(this);
item = convertView;
}
//绑定ViewHolder与item
public static ViewHolder bind(Context context, View convertView, ViewGroup parent,
int layoutRes, int position) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder(context, parent, layoutRes);
} else {
holder = (ViewHolder) convertView.getTag();
holder.item = convertView;
}
holder.position = position;
return holder;
}
@SuppressWarnings("unchecked")
public <T extends View> T getView(int id) {
T t = (T) mViews.get(id);
if (t == null) {
t = (T) item.findViewById(id);
mViews.put(id, t);
}
return t;
}
/**
* 获取当前条目
*/
public View getItemView() {
return item;
}
/**
* 获取条目位置
*/
public int getItemPosition() {
return position;
}
/**
* 设置文字
*/
public ViewHolder setText(int id, CharSequence text) {
View view = getView(id);
if (view instanceof TextView) {
((TextView) view).setText(text);
}
return this;
}
/**
* 设置图片
*/
public ViewHolder setImageResource(int id, int drawableRes) {
View view = getView(id);
if (view instanceof ImageView) {
((ImageView) view).setImageResource(drawableRes);
} else {
view.setBackgroundResource(drawableRes);
}
return this;
}
/**
* 设置图片
*/
public ViewHolder setImageResource(int id, String path) {
View view = getView(id);
if (view instanceof ImageView) {
((ImageView) view).setImageBitmap(BitmapFactory.decodeFile(path));
} else {
view.setBackground(Drawable.createFromPath(path));
}
return this;
}
/**
* 设置点击监听
*/
public ViewHolder setOnClickListener(int id, View.OnClickListener listener) {
getView(id).setOnClickListener(listener);
return this;
}
/**
* 设置可见
*/
public ViewHolder setVisibility(int id, int visible) {
getView(id).setVisibility(visible);
return this;
}
/**
* 设置标签
*/
public ViewHolder setTag(int id, Object obj) {
getView(id).setTag(obj);
return this;
}
//其他方法可自行扩展
}
}
六.总结
此次课程设计,我设计了一个智能菜谱的软件,用到了Android和SQLite数据库以及之前学到相关知识点。通过课设我学到了许多东西。我们可以自己通过重写方法或者通过实现View或者Layout等类进行扩充项目需要的布局(或者控件),在学习界面中,通过Layout文件夹下的配置文件,可以快速的形成界面,在配置文件可以设置属性或者样式都是很快捷方便。对ListView对一些视图及其监听方法的实现进行了深入的了解,熟悉了Database、Helper数据库的应用,尤其是对数据库表的创建,表中信息进行增、删、改、查的操作应用。
要设计这样一个软件,需要很强的逻辑分析,需求分析,功能实现的构思,进行模块的划分也是很重要的。课设中遇到了很多困难,报错的地方挺多,经过请教他人,网上查询和查阅书籍等才将一系列问题解决。感谢这次课程设计,让我学到了很多,也感谢指导老师的辛勤付出。
我觉得最重要的还是活学活用,能将所学知识应用于实践,并学习如何开发完成一个完整的项目。此次课程设计,使我巩固和实践了android课程知识,因此,此次课程设计对我的帮助不仅是在专业课程上更是影响以后的工作生活。我相信以后我会更懂得团队合作和克服困难,解决问题。
附件1:
智能菜谱系统
技术说明
用到了UI技术,运用了SQLite数据库存储对菜品进行增删改查,在Android studio中运用LinearLayout和RelativeLayout嵌套,主要用到的控件有Button、TextView、view、ImageView。通过在java类中定义和设置监听事件来进行点击设置相应属性。
UML类图
代码
清单文件:
布局文件:
1.截图
2.原文件
java 原码
类说明
LoginActivity类:
为“登陆成功”按钮设置监听事件,实现登录成功后的页面跳转
DetailActivity类:
有“添加收藏”,“删除收藏”,“收藏”三个按钮事件
点击收藏按钮可以在数据库表中查询添加收藏的数据,点击删除收藏按钮可以删
除表中的数据。
AddActivity类:
为“上传成功”按钮设置监听事件,实现上传成功后的页面跳转
SplashActivity类:
实现闪屏界面,如果上次退出了,则先进入登录界面,否则直接进入当时的界面
MainActivity类:
为“再按一次退出程序”按钮设置监听事件,点击该按钮将退出程序,跳转到退出后的界面
以上是关于智能菜谱课程设计报告的主要内容,如果未能解决你的问题,请参考以下文章