跳到主要内容

点餐系统学习报告

学习要点

Spinner下拉选择框

实现步骤

  1. 在XML中创建 Spinner 组件
  2. 在其对应的Java文件中创建String类型的数组变量,并将选项的值放入对应的数组
  3. 使用Spinner自带的 setAdapter() 方法设置适配器和下拉选择框的模板

部分代码

MainActivity.java
public class MainActivity extends AppCompatActivity {
Spinner sptable, spdate, sptime;
String[] tables = {"请选择餐桌类型", "小桌(2 座)", "中桌(4 座)", "大桌(8 座)", "房间(12座)"};
String[] dates = new String[8];
String[] times = {"请选择就餐时间", "08:00 一 10:00", "10:00 一 12:00", "12:00 一 14:00", "14:00 一 16:00",
"16:00 一 18:00", "18:00 一 20:00"};
Button btnselok;
boolean isFirstItemSelected1, isFirstItemSelected2, isFirstItemSelected3; //用于判断是否不是默认选项
String sel1, sel2, sel3;

...

private void initListener() {
sptable.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i == 0) {
isFirstItemSelected1 = true;
} else {
isFirstItemSelected1 = false;
}
sel1 = adapterView.getSelectedItem().toString();
}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {

}
});
spdate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i == 0) {
isFirstItemSelected2 = true;
} else {
isFirstItemSelected2 = false;
}
sel2 = adapterView.getSelectedItem().toString();
}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {

}
});
sptime.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i == 0) {
isFirstItemSelected3 = true;
} else {
isFirstItemSelected3 = false;
}
sel3 = adapterView.getSelectedItem().toString();
}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {

}
});
//确认按钮点击事件
btnselok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isFirstItemSelected1 && !isFirstItemSelected2 && !isFirstItemSelected3) {
startActivity(new Intent(MainActivity.this, MenuPage.class)
.putExtra("table", sel1)
.putExtra("date", sel2)
.putExtra("time", sel3));
} else {
Toast.makeText(MainActivity.this, "请选择相关选项后再继续操作", Toast.LENGTH_SHORT).show();
}
}
});
}

private void judge() {
if (!okhttp.GetBoolean(MainActivity.this, "isopen")) {
sptable.setAdapter(new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item, tables));
Calendar cal = Calendar.getInstance();
dates[0] = "请选择就餐日期";
for (int i = 1; i <= 7; i++) {
dates[i] = new SimpleDateFormat("yyyy年M月d日").format(cal.getTime());
cal.add(Calendar.DATE, 1);
}
spdate.setAdapter(new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item, dates));
sptime.setAdapter(new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item, times));
} else {
startActivity(new Intent(MainActivity.this, SuccessPage.class)
.putExtra("bought", true));
}
}
}

OKHttp的运用

实现步骤

  1. 将OKHttp库和Gson库导入工程
  2. 新建一个Java类文件
  3. 创建一个 OkHttpClient 类型的变量,并赋值为一个新的 OkHttpClient() 方法
  4. 创建一个公开(public)的静态(static)的方法以使用Post方法获取服务器数据,其参数是两个Strin类型的变量作为接口地址和传输的内容
  5. 在方法中创建一个String类型的数组并将其设置为空
  6. 创建一个线程变量,并赋值为一个新的线程方法,其参数为一个新的 Runnable() 方法
  7. run() 方法中写入 RequestBody 类型变量和 Request 类型变量
  8. RequestBody变量使用RequestBody自带的create方法,其参数为转成 application/jsonobj 变量
  9. Request变量赋值为一个新的Request并使用 Builder()url()post()build() 方法创建请求变量
  10. 将数组变量的第一个值为OkHttpClient变量使用 newCall()execute()body()string() 方法创建请求
  11. 使用try和catch抛出异常
  12. 使用Thread自带 start()join() 方法的启动线程变量
  13. 返回一个新的JSONObject格式变量,内容是数组的第一个元素

部分代码

okhttp.java
public class okhttp {
private static OkHttpClient client = new OkHttpClient();
private static String base = "http://10.0.2.2:8080/";

public static JSONObject Post(String url, String obj) throws Exception {
String[] body = {null};
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), obj);
Request request = new Request.Builder().url(base + url).post(requestBody).build();
try {
body[0] = client.newCall(request).execute().body().string();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
thread.join();
return new JSONObject(body[0]);
}

public static Bitmap Bitmap(String net) throws Exception {
Bitmap[] bitmaps = {null};
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
bitmaps[0] = BitmapFactory.decodeStream(new URL(net).openStream());
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
thread.join();
return bitmaps[0];
}
}

倒计时

实现步骤

  1. 新建一个 CountDownTimer() 方法,第一个值是倒计时的总时间,第二个值是每次变化的时间
  2. onTick() 方法是每一次倒计时的事件
  3. 设置每次倒计时的事件为显示倒计时的秒钟,millisUntilFinished 变量代表剩余倒计时的事件
  4. onFinish() 方法是倒计时结束的事件
  5. 最后使用 start() 方法启动这个倒计时

部分代码

PayPage.java
...
new CountDownTimer(60000, 1000) {
public void onTick(long millisUntilFinished) {
tvcd.setText(millisUntilFinished / 1000 + "");
}

public void onFinish() {
finish();
Toast.makeText(PayPage.this, "支付超时,请重试", Toast.LENGTH_SHORT).show();
}
}.start();

SQLite数据库的运用

实现步骤

  1. 新建一个Java类文件并继承 SQLiteOpenHelper 的方法
  2. onCreate() 方法中写入创建数据表的SQL语句
  3. 在需要和数据库交互的页面创建 SQLiteOpenHelperSQLiteDatabase 类型的变量
  4. SQLiteOpenHelper变量赋值为一个新的 sql() 方法来创建数据库连接
  5. SQLiteDatabase变量使用 getWritableDatabase() 方法来获取交互权
  6. 使用游标(Cursor)来定位数据库并进行交互操作,如:getString()、getColumnIndex()等
  7. 使用SQLiteDatabase自带的 execSQL 方法执行SQL语句

部分代码

sql.java
public class sql extends SQLiteOpenHelper {
Context context;

public sql(@Nullable @org.jetbrains.annotations.Nullable Context context,
@Nullable @org.jetbrains.annotations.Nullable String name,
@Nullable @org.jetbrains.annotations.Nullable SQLiteDatabase.CursorFactory factory, int version, Context context1) {
super(context, name, factory, version);
this.context = context1;
}

public sql(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE t_menu (data text) ");
sqLiteDatabase.execSQL("CREATE TABLE t_user (tabletype text,eattime text,eatdate text) ");
}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

}
}
Success.java
public class SuccessPage extends AppCompatActivity {
...
SQLiteOpenHelper dbhelper;
SQLiteDatabase db;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_success_page);
dbhelper = new sql(SuccessPage.this, "sql.db", null, 1);
db = dbhelper.getWritableDatabase();
...
}

private void judge() {
if (getIntent().getBooleanExtra("bought", false)) {
Type type = new TypeToken<List<Food>>() {
}.getType();
Cursor cursor = db.rawQuery("SELECT * FROM t_menu", null);
cursor.moveToFirst();
lvsetmenu.setAdapter(new PayAdapter(SuccessPage.this,
new Gson().fromJson(cursor.getString(cursor.getColumnIndex("data")), type)));
cursor = db.rawQuery("SELECT * FROM t_user", null);
cursor.moveToFirst();
tvsettable.setText(cursor.getString(cursor.getColumnIndex("tabletype")));
tvsetdate.setText(cursor.getString(cursor.getColumnIndex("eatdate")));
tvsettime.setText(cursor.getString(cursor.getColumnIndex("eattime")));
} else {
lvsetmenu.setAdapter(new PayAdapter(SuccessPage.this, MenuPage.buyfoodList));
tvsettable.setText(MenuPage.table);
tvsetdate.setText(MenuPage.date);
tvsettime.setText(MenuPage.time);
okhttp.SaveBoolean(SuccessPage.this, "isopen", true);
db.execSQL("INSERT INTO t_menu (data) VALUES ('" + new Gson().toJson(MenuPage.buyfoodList) + "')");
db.execSQL("INSERT INTO t_user (tabletype,eattime,eatdate) VALUES ('" + MenuPage.table + "','" + MenuPage.time + "','" + MenuPage.date + "')");
}
}
}

学习心得

通过这次点餐系统的制作,相较于之前的开发,又新接触了许多知识点,如:下拉选择、网络读取、JSON解析、倒计时、SQLite数据库等,其中我认为SQLite数据库的应用是比较重要的一点,因为数据库是在应用开发中非常常用且成熟的技术。