目录

1.背景介绍

2.需求分析

2.1待解决问题

2.2 解决方式

3.开发环境

3.1开发工具简介

3.2开发语言简介

4.功能介绍

5.程序实现及关键代码分析

5.1“添加食材”功能实现及分析

5.1.1基于本地数据库的数据持久化

5.1.2 界面设计

5.2“菜篮状况”功能实现及分析

5.2.1动态SQL语句分类查找

5.2.2 界面设计

5.3“菜篮状况”功能实现及分析

5.3.1简易数据分析实现

5.3.2界面设计

5.4“养生建议”功能实现及分析

5.4.1网站列表实现(WebView)

5.4.2 界面设计

5..5 “备忘记录”功能实现及分析

5.5.1 基于本地数据库的内嵌记事本实现

5.5.2 界面设计

5.6 “菜篮管理”功能实现及分析

5.6.1 菜篮数据库增删实现

5.6.2界面设计

5.7 “菜谱搜索”功能实现及代码分析

5.7.1 API接口调用与JSON数据解析

5.7.2 界面设计

5.8 “私人收藏”功能实现及代码分析

5.8.1 基于文本文件(TXT)数据持久化技术

5.8.2 界面设计

1.背景介绍

健康是一种人在身体与精神上的完全统一的状态,根据世卫组织(WHO)的统计数据,中国居民中符合世卫组织对健康的定义的人数只占总人口的15%,并且有同等比例的人群处在疾病状态中,剩下近十分之七的人处在所谓“亚健康”状态。

后疫情时代,健康已成为当下热点话题之一,健康消费也正逐步渗透到更多的生活领域当中,与此同时,市场上关于生活与健康的APP数目也逐渐增多,包括keep等健身软件,今日养生等健康知识软件,果蔬百科等生活常识软件多种类型。

而健康饮食是指恰当选择搭配合理和适当份量的食物进行食用,人体摄入各种营养素和恰当热量去维持身体细胞的正常生长,增强身体对疾病的抵抗力和维持一定的体重。.

饮食健康因为与人们日常生活的息息相关,又格外被人们所重视,食材的新鲜程度,菜谱搭配合理与否,都是影响厨房能否高效运行,家人的饮食健康的关键因素。

2.需求分析

2.1待解决问题

后疫情时代,新冠疫情防控常态化关键时期,为响应政府号召,民众减少外出,居家抗疫;屯菜也成为不可避免的生活常态。

购菜数目的增长往往带来管理的混乱,列举如下:

  1. 一,在菜市场时,常常忘记家中还余哪些菜,担心买重(复)或是无法搭配而导致食材的闲置与浪费。
  2. 二,忽略了食材的购买时间,摄入了变质食材;又或是烹饪方法错误,将产生不良化学反应的食材进行了混合食用,造成恶性食物中毒事件。
  3. 三,在家时冰箱难以整理,偶尔将某些食材遗忘在冰箱角落,再找到时已然无法食用或是新鲜不再。
  4. 四,厨房中,发觉某类食材与其他食材间不能够进行有效搭配,又或是不知如何对其进行正确烹饪,造成不必要的浪费。

2.2 解决方式

为做好家庭食材的管理,借助Android移动端对购买食材信息进行记录,将已购的食材录入到移动端,便捷民众整理与记忆,做到购菜时心中有数(解决问题一/三),时刻关注到菜篮中食材的新鲜程度,包括照片间的比对,购入时间的记录等等(解决问题二)。

同时该APP提供了大量正确有效的烹饪方法,在使用过程中用户能够锻炼厨艺(解决问题四),提升生活质量,进行高品质饮食。

3.开发环境

该软件设计基于安卓(Android)进行开发,安卓(Android)是基于Linux内核基础的自由开放源代码的操作系统,适用于便捷携带的设备,如智能手持设备;随后在其发展的过程中不断扩展到其他领域中,例如平板电脑等。安卓(Android)由美国Google公司收购注资。

3.1开发工具简介

Android Studio 是美国Google公司推出的Android集成开发环境,整体架构与JetBrains旗下的IntelliJ IDEA类似,并提供了相似的开发调试工具。

3.2开发语言简介

Android采取代码与布局相分离的方式对项目进行组织,由Java语言编写内部的逻辑,XML语言修改调整布局界面。

Java:最为广泛使用的编程语言之一,也是Android开发的基础。

XML: 可扩展标记语言,标准通用标记语言的子集。

4.功能介绍

  1. 添加食材,用户录入其数据信息,并将照片保存从而将购买的食材录入“菜篮”。
  2. 菜篮空间,对食材进行分类展示。
  3. 菜篮状况,对当前菜篮空间进行数据分析,柱状图的直观展示与分类统计。
  4. 养生建议,推送一定健康小常识文章。
  5. 备忘记录,内嵌记事本,帮助记忆。
  6. 菜篮管理,对菜篮进行删查操作,支持用户删除与查找食材。
  7. 菜谱搜索,通过关键词检索网络接口,获取各类食材的常见烹饪做法。
  8. 私人收藏,对喜爱的做法进行收藏。

5.程序实现及关键代码分析

5.1“添加食材”功能实现及分析

5.1.1基于本地数据库的数据持久化

考虑到菜篮中的食材数据是本手机软件(APP)的关键数据,而保存在文件系统中的数据文件分散程度较高,程序难以读取与管理;采用本地数据库对数据进行存储,数据库技术能够帮助我们实现数据共享,避免不同用户建立独立的重复数据,从而进行数据的集中统一控制管理。

通过food_store.class文件创建数据库(见下方代码),并实现了对数据库的增删改查操作,利用TextView对查询数据的正确性进行了测试。

food_store_database helper;

helper = new food_store_database(food_store.this, "basket.db", null, 1);

Button create_basket = (Button) findViewById(R.id.button1);

create_basket.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

helper.getWritableDatabase();

}

});

针对食材建立了basket.db文件,并执行SQL语句创建表basket

其各字段的数据类型、索引与字段名如下

索引

字段名称

数据类型

解释

0

id

整型

主键

1

name

字符串

名称

2

date

字符串

购入时间

3

price

实数

价格

4

time

实数

保鲜时长

5

timeunit

字符串

保鲜时长单位

6

number

实数

数目

7

numberunit

字符串

数目单位

8

classify

字符串

类别

9

address

字符串

图片地址

public  static final String CREATE_basket="create table basket("

+"id integer primary key autoincrement,"

+ "name text,"

+ "date text,"

+ "price real,"

+ "time real,"

+ "timeunit text,"

+ "number real,"

+ "numberunit text,"

+ "classify text,"

+ "address text)";

db.execSQL(CREATE_basket);

创建数据库表格表basket关键代码如下:

5.1.2 界面设计

<style name="Theme.Basket" parent="Theme.MaterialComponents.DayNight.NoActionBar">

数据库建立后,建立“添加食材”页面,为了制作自定义顶部栏,修改themes.xml文件去除了页面的默认顶部栏。

利用layout代码,自定义了基础的顶部栏,在其中添加了“<”(返回)ImageButton 以实现界面跳转,从而使得页面逻辑通顺。

为实现用户调用相机拍照,并将JPG文件存储至数据库的功能,实现FileProvider类,并在res资源文件路径下建立file_paths.xml文件,从而指定文件存储路径。

调用相机拍照并进行存储的关键代码如下:

用户点击拍照后,照片路径便被存储在数据库中,而其路径下对应的图片存储在虚拟机的内存文件中。

image_uri=FileProvider.getUriForFile(food_add.this,"com.example.Basket.fileprovider",outputImage); Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

intent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);

startActivityForResult(intent, 1);

路径例如“/storage/emulated/0/Android/data/com.example.basket/cache/id3.jpg”

通过这种组织方式,能够将不定量数目的图片有效存储,而不是依赖于Android R中的资源文件。

通过EditText文本框获取用户输入,并将信息组织为一条长记录,插入在数据库中,以ID作为主键从而保证对数据库的操作不会出错。

利用EditText的setText(null)方法与picture.setVisibility(View.GONE)方法;,将用户的输入与照片清空,便捷用户下一轮的输入。

5.2“菜篮状况”功能实现及分析

5.2.1动态SQL语句分类查找

check_classify[0] =classify[position];

//准备数据 在此查询数据库

String name;

String path;

//需要获取名称与图片路径

Cursor cursor_food = db.rawQuery("select * from Basket where classify =?", new String[]{check_classify[0]});

动态调整SQL语句,从而获取不同分类

用户进行分类的选择,因此需要实现界面左侧classify的ListView,根据用户对ListView的点击事件来获取用户选择的分类,同步更新右侧ListView展示食材:

将分类查询数据库后的获取的食材列表分配适配器中,并加载ListView:

//准备菜篮食物列表listview_

ListView listView_ = (ListView) findViewById(R.id.food_list);

//准备food_list 适配器

FoodAdaper adapter_ = new FoodAdaper(basket_food_.this, R.layout.fooditem, foodList);

listView_.setAdapter(adapter_);

listView_.setOnItemClickListener(new AdapterView.OnItemClickListener() {

5.2.2 界面设计

为使得布局清晰,使用ImageView与ListView类进行线性布局的排布;左侧为类别列表,其包含项目为“蔬菜”“豆制”“水产”“肉禽”“水果”“速食”“饮品”“辅料”“粮油”

而右侧列表为数据库中食材内容,通过对数据库的查询结果来填充。

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

int jcdun;

for(jcdun=0;jcdun<listView_classify.getChildCount();jcdun++){

View tv = listView_classify.getChildAt(jcdun);

tv.setBackgroundColor(Color.parseColor("#f7f7f7"));

//利用整数jcdun遍历整个listview

//将所有的背景色设置为默认的灰色

}

listView_classify.getChildAt(

position-listView_classify.getFirstVisiblePosition())

.setBackgroundColor(Color.parseColor("#fd8e0a"));

//将选中的方框背景色修改为橙色

为了使得界面更加美化,修改并调整分类列表选中项的背景色,并保证其他未被选中项中背景色为灰色,该效果使用ListView. setOnItemClickListener与View.setBackgroundColor实现,关键代码如下:

RadioGroup radioGroup = (RadioGroup) findViewById(R.id.food_tap);

RadioButton radioButton = (RadioButton) findViewById(radioGroup.getCheckedRadioButtonId());

TextView textView = (TextView) findViewById(R.id.food_top_title);

radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

@Override

public void onCheckedChanged(RadioGroup group, int checkedId) {

if (checkedId == R.id.food_tab_home) {

textView.setText("首页");

Intent it = new Intent(getApplicationContext(), home_.class);

startActivity(it);

} else if (checkedId == R.id.food_tab_book) {

textView.setText("食谱");

Intent it = new Intent(getApplicationContext(), book.class);

startActivity(it);

} else if (checkedId == R.id.food_tab_food) {

textView.setText("菜篮");

} else if (checkedId == R.id.food_tab_my) {

textView.setText("我的");

Intent it = new Intent(getApplicationContext(), mine.class);

startActivity(it);}}});

底部栏使用单选框RadioGroup实现,通过监听底部栏的状态变化(用户点击),更改顶部栏文字并进行页面的跳转。

利用XML文件修改底部栏的显示,使得被选中的页面底部栏图标变色,这在一定程度上能够提升用户的交互体验:利用Style文件定义风格,能够帮助我们降低工作量,提高代码复用率,在各个主页面的底部,都可以添加该Style的底部栏。

<style name="tab_menu_item">

<item name="android:layout_width">0dp</item>

<item name="android:layout_weight">1</item>

<item name="android:layout_height">match_parent</item>

<item name="android:button">@null</item>

<item name="android:gravity">center</item>

<item name="android:textColor">@drawable/home1_text</item>

<item name="android:textSize">18sp</item>

</style>

5.3“菜篮状况”功能实现及分析

5.3.1简易数据分析实现

paintAxes = new Paint();     //画轴(横轴和竖轴)

paintAxes.setStyle(Paint.Style.STROKE);

paintAxes.setAntiAlias(true);

paintAxes.setDither(true);

paintAxes.setColor(ContextCompat.getColor(getContext(), colors.get(0)));

paintAxes.setStrokeWidth(1);

paintCoordinate = new Paint(Paint.ANTI_ALIAS_FLAG);    //画坐标(文字或数值)

paintCoordinate.setColor(ContextCompat.getColor(getContext(), colors.get(1)));

paintCoordinate.setTextSize(22f);

paintRectF = new Paint();       //画矩形

paintRectF.setColor(ContextCompat.getColor(getContext(), colors.get(2)));

paintRectF.setStyle(Paint.Style.FILL);

paintRectF.setDither(true);

paintRectF.setAntiAlias(true);

该功能与“添加食材”功能为同一页面的子页面,用于对当前用户添加数据构建的菜篮空间进行数据分析,利用常规的柱状图作直观展示与分类统计,分类统计实现较为简单,自数据库中进行查询,利用计数语句count进行分类计算即可,柱状图的构建较为困难,参考网络代码以及结合自身数据类型与大小进行修改调整,在画布上进行绘制,最终得到一个简单的效果。

5.3.2界面设计

该界面内容较少,利用简单的布局;将图片放置在上方,文字内容放置在下方,每行数据利用LinearLayout框架容纳,并在不同的线性布局框间利用外边距隔开,从而表现出整齐分布而又存在间隔的排版模式。

5.4“养生建议”功能实现及分析

5.4.1网站列表实现(WebView)

顶部利用常规顶部栏,利用SetText()方法修改其中TextView文字即可;而后使用ListView展示养生建议网站,每一项目使用WebView+TextView的形式实现,同步设计点击事件,当用户对具体的项目进行单击,我们能够跳转界面,利用WebView进入相应网站;此处的网站是本地保存的,并非网络实时爬取,但访问仍需要联网进行。

WebView items = (WebView)findViewById(R.id.good_health_item);

// 使用Intent对象得到传过来的参数

Intent intent = getIntent();

String list = intent.getStringExtra("name");

items.loadUrl(list);

关键代码:获取列表页面传参 loadUrl WebView

5.4.2 界面设计

列表页使用ListView展示,详情页使用WebView展示。

5..5 “备忘记录”功能实现及分析

5.5.1 基于本地数据库的内嵌记事本实现

在APP中内嵌记事本,帮助用户进行便捷快速记忆部分无法被记录在菜篮中的内容,以一种更加自由的方式进行备忘。

通过“我的”页面 点击“待办”跳转到内嵌记事本中,通过添加记录,实时更新数据库来保存用户输入,通过ListView展示已保存笔记

public boolean onItemLongClick(AdapterView<?> parent, View view, final intposition, long id) {

AlertDialog dialog;

AlertDialog.Builder builder = new AlertDialog.Builder( onenote.this).setMessage("是否删除此事件?").setPositiveButton("确定", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

OnenoteBean notepadBean = list.get(position);

if(mSQLiteHelper.deleteData(notepadBean.getId())){

list.remove(position);

adapter.notifyDataSetChanged();

Toast.makeText(onenote.this,"删除成功",

Toast.LENGTH_SHORT).show();

}

}

})

支持数据库的增删操作,能够通过长按,实现对笔记的删除,关键代码如下。

5.5.2 界面设计

5.6 “菜篮管理”功能实现及分析

5.6.1 菜篮数据库增删实现

对菜篮进行删查操作,支持用户删除与查找食材,当用户发觉食材过期/变质,或是已经将家中某项食材完全消耗,应当支持用户对其进行删除,从而为之后的输入腾出空间。

利用长按方法进行删除,同步执行数据库内删除与listView中remove。

查找应该属于数据库的基本操作,而对菜篮的查找,也能够为用户带来更好的用户体验,在实际APP中,查找往往是不可避免的操作。

利用SQL中like子句对数据库进行模糊匹配查询的关键代码如下:

Cursor cursor_food =

db.rawQuery("select * from Basket where name like '%"

+ home_search_food_name.getText().toString() + "%'", null);

if (cursor_food.moveToFirst()) {

do{

name = (cursor_food.getString(1));

path = (cursor_food.getString(9));

File file = new File(path);

if(file.exists()){

Bitmap bm = BitmapFactory.decodeFile(path);

foodList.add(new food(name, bm));  }}

while(cursor_food.moveToNext());}

cursor_food.close();

5.6.2界面设计

查询部分并未制作新界面,而是利用控件View的可见性Visibility进行控制,当用户点击搜索按钮,对数据库进行查询并将内容填充在ListView中,并将其他内容进行隐藏,而后点击取消,将内容可见性进行交换,从而实现单页面内的工作。

5.7 “菜谱搜索”功能实现及代码分析

5.7.1 API接口调用与JSON数据解析

通过用户在EditText中输入或是通过菜篮详情页跳转传参,将其作为关键词检索网络接口,获取各类食材的常见烹饪做法

该部分功能难点在于API接口的连接,需要一定网络请求知识与相关的JSON数据解析能力。

用于解析JSON数据的关键代码如下:

public void handleMessage(@NonNull Message msg) {

// 解析JSON数据 从中获得我需要的内容!

super.handleMessage(msg);

if (msg.what == 0) {

String strData = (String) msg.obj;

str=strData;

JSONObject jsonObject1;

try {

jsonObject1 =

new JSONObject(str);

// 整个JSON对象

JSONObject jsonObject2=jsonObject1.getJSONObject("result");

// 进入result部分

JSONArray arr = jsonObject2.getJSONArray("list");

// 进入result-list部分

for(int i=0;i<30;i++){

jsonObject1 = arr.getJSONObject(i);

foodList.add(new book_food(jsonObject1.opt("name").toString(),jsonObject1.opt("pic").toString()));

}

//读取三十个结果

} catch (JSONException e) {

e.printStackTrace();

}

而网络请求的关键代码如下:(在主线程中的HTTP请求,运行时都会报错)

public void start(View view) {

new Thread(new Runnable() {

public void run() {

String stringFromNet = getStringFromNet();

Message message = new Message();

message.what = 0;

message.obj = stringFromNet;

mHandler.sendMessage(message); }}).start();

ext(this,"开启子线程请求网络!",Toast.LENGTH_SHORT).show();

}

<uses-permission android:name="android.permission.INTERNET" />

当然,连接API接口前需要申请网络权限,并打开虚拟机的wifi功能

5.7.2 界面设计

5.8 “私人收藏”功能实现及代码分析

5.8.1 基于文本文件(TXT)数据持久化技术

在上述菜谱查询的过程中,用户若发现喜爱的食谱做法,可以建立单人的收藏夹,对喜爱的做法进行收藏,并能够通过单独的页面展示。

对此我使用了文本txt文件来做数据持久化的工作,当用户长按列表中的某类食谱,能够弹窗提示是否收藏,若用户点击收藏,则我将该记录的数据追加到txt的末尾处,并在收藏页中利用ListView进行简单展示,若用户选择取消,则弹窗关闭。

public static void savefile(String file, String conent) {        BufferedWriter out = null;

try {

out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));

out.write(conent);

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if(out != null){

out.close();}

} catch (IOException e) {

e.printStackTrace();}}}

savefile( )将收藏内容添加到内存中txt文件中的方法,

关键代码如下

private String loadFromSDFile(String fname) {

String result=null;

try {

File f=new File(fname);

int length=(int)f.length();

byte[] buff=new byte[length];

FileInputStream fin=new FileInputStream(f);

fin.read(buff);

fin.close();

result=new String(buff,"UTF-8");

}catch (Exception e){

e.printStackTrace();

Toast.makeText(shoucang.this,"没有找到指定文件",Toast.LENGTH_SHORT).show();

}

return result;

}

将SD卡内存中文件读取为String字符串

5.8.2 界面设计

移动应用开发:Android Studio实现个人购菜/食谱管理系统相关推荐

  1. android studio socket 失败,Android应用开发Android Studio建立Socket连接失败解决方法

    本文将带你了解Android应用开发Android Studio建立Socket连接失败解决方法,希望本文对大家学Android有所帮助. < Android Studio建立Socket连接失 ...

  2. android studio获取数字签名,Android应用开发Android Studio数字签名打包apk图文步骤教程...

    本文将带你了解Android应用开发Android Studio数字签名打包apk图文步骤教程,希望本文对大家学Android有所帮助. Android Studio数字签名打包release版apk ...

  3. android修改用户名和密码错误,Android应用开发Android Studio 修改用户名、密码、URL等操作教程...

    本文将带你了解Android应用开发Android Studio 修改用户名.密码.URL等操作教程,希望本文对大家学Android有所帮助. 修改用户名.密码: 在AndroidStudio的ter ...

  4. android程序包不存在,Android应用开发Android studio 错误: 程序包 不存在

    本文将带你了解Android应用开发Android studio 错误: 程序包 不存在,希望本文对大家学Android有所帮助. " Android studio 错误: 程序包 不存在 ...

  5. android studio真机测试不生成apk,Android应用开发Android Studio编译出来的APK无法安装如何解决?...

    本文将带你了解Android应用开发Android Studio编译出来的APK无法安装如何解决?,希望本文对大家学Android有所帮助. Android Studio编译出来的APK无法安装如何解 ...

  6. 小米5 android studio,Android应用开发android studio运行app,使用模拟器可以,用小米5手机安装失败...

    本文将带你了解Android应用开发android studio运行app,使用模拟器可以,用小米5手机安装失败,希望本文对大家学Android有所帮助. < 报错 Session 'app': ...

  7. Android开发-Android studio自带模拟器使用中文拼音输入法

    Android开发-Android studio自带模拟器使用中文拼音输入法 搜狗输入法下载 搜狗输入法安装 修改模拟器语言 搜狗输入法下载 上篇文章中我们在Android studio中创建了X86 ...

  8. android studio密钥库口令,Android应用开发Android Studio签名打包及根据keystore密钥获取SHA1安全码...

    本文将带你了解Android应用开发Android Studio签名打包及根据keystore密钥获取SHA1安全码,希望本文对大家学Android有所帮助. " 一.签名打包两种方式 1. ...

  9. Android开发——Android Studio中配置及使用OpenCV示例

    from: http://www.mobile-open.com/2015/86176.html 本文主要讲述了Android Studio中配置及使用OpenCV示例,现在整理出来分享给Androi ...

最新文章

  1. FPGA基础知识极简教程(9)七段数码管显示的Verilog简单设计
  2. 大话数据库连接池简史,你都用过几个?
  3. 开发中经常碰到的问题cookie和session问题,今天一并解决
  4. case是java关键字吗_Java关键字
  5. Atitit 收入理论大总结 4位一体 4象限理论 财政收入理论 6位一体
  6. UE4 C++头文件
  7. 破解StarUML4.1.6
  8. matlab 数据字典,以编程方式将数据存储到字典中
  9. 计算机类中文核心期刊
  10. 计算机英语单词怎么巧背,怎么快速背记英语单词
  11. 【实习日报】2019年3月 前端开发实习工作日报汇总
  12. 王者服务器维护公告2月,2月26日全服不停机更新公告
  13. Vue实战篇三十四:给新闻WebApp加入模拟注册登录功能
  14. 加速信创落地,最新国产身份目录服务首发
  15. c++高级编程学习笔记4
  16. 给MFC控件添加提示信息
  17. RHCE认证考试心得(转)
  18. iOS中 HeathKit框架学习 步数统计等 韩俊强的博客
  19. 软件工程第1次作业:阅读教材,提五个问题
  20. Excel-开发者工具

热门文章

  1. 去掉word2007里文档结构图目录底色的方法
  2. 海康、大华等IpCamera RTSP地址和格式
  3. Find My资讯|新系统苹果Find My不再显示AirTag电池电量
  4. python 实现 画图器_按钮实现Python--绘图工具matplotlib的使用
  5. 保存微信公众号付费文章至本地的方法
  6. 那些优秀的开源系统恢复软件
  7. 在局域网对数据库SQL Server和文件备份的方法
  8. 我的世界怎么修改服务器地皮语,我的世界服务器地皮怎么设置移动权限
  9. Neuron:精神病学中的功能神经成像和失败案例
  10. ffmpeg 字体android,FFMPEG:添加字体到视频给出错误