Tags: Android

每天一到吃饭时间就会很纠结,今天吃什么,所以就有了这个APP。事先将想吃的输入进APP里,APP就会随机挑选出一个结果,解决选择困难症。

1.基本思路与核心技术

(1)随机数生成

整个APP的核心就是随机数生成以及数据操作。在JAVA中,生成随机数利用Math.random()即可,会生成一个0(包含)到1(不包含)的浮点数,近似均匀分布。对于要生成覆盖全部list元素的整形随机数可以这样写。

int length = foods.size();
int select_index = (int) (Math.random() * (length + 1) - 1);
(2)数据交互与持久化

其次就是数据的操作了,类似于数据库,要有增、删、改、查四个最基本的操作。所以单独定义了增加和修改对话框,以及通过ListView的上下文菜单实现长按删除操作。整体架构很类似之前写的体重记录器,只是更简单些。这个APP从代码到界面,都保持比较简洁的风格。

这是基本的数据交互,但还需要将数据持久化,即保存起来,这样下次用户再打开APP的时候上次添加的数据都还在。要实现这个可以有多种方式,一种是保存APP设置等参数常用的SharedPreference,另一种是采用SQLite数据库。还有一种比较直接的办法就是将数据按照自己的格式保存成txt文件,每次打开APP时再按照格式读取这个文件。 这种方法“简单粗暴”,难度较小,对于数据不复杂、量不大的情况比较适用。这里采用的就是这种方法。

下面这段代码就是用来保存数据的。

String Results = "";
for (int i = 0; i < MainActivity.foods.size(); i++) {
    Results += MainActivity.foods.get(i).getName() + "\t" + MainActivity.foods.get(i).getPs() + "\n";
}
File file = new File(MainActivity.FileName);
FileOutputStream fos = null;
try {
    fos = new FileOutputStream(file);
    fos.write(Results.replace("\n", "\r\n").getBytes());
    fos.close();
} catch (Exception e) {
    e.printStackTrace();
}
Log.d("Save file", "Save file");

下面这段代码则是用于读取数据。这段代码是放在主界面的OnCreate()启动函数中的,因此有两个作用。对于第一次启动,没有数据文件时,主动建立一个空的数据文件。如果有数据文件则对文件进行读取。

context = getApplicationContext();
path = context.getFilesDir() + "/";
File filedir = new File(path);
if (!filedir.exists()) {
	filedir.mkdir();
}

FileName = path + "foods" + ".txt";
File file = new File(FileName);
if (file.exists()) {
	try {
		Log.d("Load file", "Load file");
		foods.clear();
		InputStream inputStream = null;
		inputStream = new FileInputStream(file);
		InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
		String temp;
		try {
			while ((temp = bufferedReader.readLine()) != null) {
				String[] numbers = temp.split("\t");
				String foodname = numbers[0];
				String foodps;
				if (numbers.length == 1) {
					foodps = "";
				} else {
					foodps = numbers[1];
				}
				Food foodTemp = new Food(foodname, foodps);
				foods.add(foodTemp);
				inputStream.close();
			}
			inputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}
} else {
	Log.d("Create file", "Create file");
	FileOutputStream fos = null;
	try {
		fos = new FileOutputStream(file);
		fos.write("".getBytes());
		fos.close();
	} catch (Exception e) {
		e.printStackTrace();
	}
}
(3)界面动画

为了给APP增加点乐趣,在点击主界面的大图标时会旋转一圈,然后给用户结果,可以给用户增加一点选择的“仪式感”,让选择结果从心理上更有分量一些。添加动画的代码比较简单,如下。

public void rotateAnim() {
        Animation anim = new RotateAnimation(0f,
                360f,
                Animation.RELATIVE_TO_SELF,
                0.5f,
                Animation.RELATIVE_TO_SELF,
                0.5f);
        anim.setFillAfter(true); // 设置保持动画最后的状态
        anim.setDuration(1000); // 设置动画时间
        anim.setInterpolator(new AccelerateDecelerateInterpolator()); // 设置插入器
        iv_select.startAnimation(anim);
    }
(4)随机显示图片

由于APP用户可能每天都会打开多次,因此如果界面一尘不变的话很容易让用户厌倦。因此对于主界面的图标,选择了许多不同的图片,这里选择了50张图片。每次打开APP的时候都会随机显示一张,这样有助于增加用户的新鲜感。

public void randomImage() {
        List<Integer> imgs = new ArrayList<>();
        imgs.add(R.drawable.img_chopsticks);
        imgs.add(R.drawable.img_fork);
        imgs.add(R.drawable.img_fork2);
        imgs.add(R.drawable.img_spoon);

        imgs.add(R.drawable.img_apple);
        imgs.add(R.drawable.img_banana);
        imgs.add(R.drawable.img_baozi);
        imgs.add(R.drawable.img_beef);
        imgs.add(R.drawable.img_bread);
        imgs.add(R.drawable.img_cabbage);
        imgs.add(R.drawable.img_cake);
        imgs.add(R.drawable.img_carrot);
        imgs.add(R.drawable.img_cheese);
        imgs.add(R.drawable.img_cherry);
        imgs.add(R.drawable.img_chicken);
        imgs.add(R.drawable.img_chips);
        imgs.add(R.drawable.img_chips2);
        imgs.add(R.drawable.img_coffee);
        imgs.add(R.drawable.img_coke);
        imgs.add(R.drawable.img_cookie);
        imgs.add(R.drawable.img_donut);
        imgs.add(R.drawable.img_eggs);
        imgs.add(R.drawable.img_fish);
        imgs.add(R.drawable.img_hamburger);
        imgs.add(R.drawable.img_hotdog);
        imgs.add(R.drawable.img_ice_cream);
        imgs.add(R.drawable.img_ice_cream2);
        imgs.add(R.drawable.img_juice);
        imgs.add(R.drawable.img_lobster);
        imgs.add(R.drawable.img_milk);
        imgs.add(R.drawable.img_milk2);
        imgs.add(R.drawable.img_milk3);
        imgs.add(R.drawable.img_noodles);
        imgs.add(R.drawable.img_noodles2);
        imgs.add(R.drawable.img_octopus);
        imgs.add(R.drawable.img_orange);
        imgs.add(R.drawable.img_orange_juice);
        imgs.add(R.drawable.img_pistachio);
        imgs.add(R.drawable.img_pizza);
        imgs.add(R.drawable.img_porridge);
        imgs.add(R.drawable.img_pudding);
        imgs.add(R.drawable.img_rice);
        imgs.add(R.drawable.img_rice2);
        imgs.add(R.drawable.img_sausage);
        imgs.add(R.drawable.img_strawberry);
        imgs.add(R.drawable.img_sushi);
        imgs.add(R.drawable.img_watermelon);
        imgs.add(R.drawable.img_watermelon2);
        imgs.add(R.drawable.img_watermelon3);
        imgs.add(R.drawable.img_yogurt);

        int length = imgs.size();
        int random_index = (int) (Math.random() * (length - 1));
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.get(random_index));
        iv_select.setImageBitmap(bitmap);
    }

最后,项目代码以及APK安装包放在了Github上,叫做WhatToEatToday,点击查看

2.测试

演示视频如下。

本文作者原创,未经许可不得转载,谢谢配合

返回顶部