Android ChangePlanActivity 代码分析:编程思路、设计思路和功能实现
ChangePlanActivity 代码分析:编程思路、设计思路和功能实现
ChangePlanActivity 是一个 Android Activity 类,用于处理用户修改学习计划的操作。它允许用户设置每天需要背诵的单词数量,并根据用户的选择进行数据下载、解析和存储。
编程思路
ChangePlanActivity 的主要逻辑如下:
- 初始化控件:在 onCreate() 方法中初始化界面上的所有控件,如 EditText、TextView 和 Button。
- 获取用户配置信息:从数据库中获取之前保存的用户配置信息,包括用户选择的单词书和背诵数量等。
- 设置最大背诵数量和书名:根据获取的用户配置信息,设置界面上显示的最大背诵数量和书名。
- 处理用户输入:当用户在 EditText 输入新的背诵数量并点击“确定”按钮时,根据用户输入更新用户配置信息。
- 数据下载和解析:如果用户是第一次设置计划,则需要下载对应的单词数据包并进行解析。这个过程在子线程中完成,以避免阻塞主线程。
- 重置学习时间和删除打卡记录:如果用户修改了计划,需要重置上次学习时间和删除当天打卡记录。
- 跳转到主页面:完成计划设置后,跳转到 MainActivity 页面。
设计思路
ChangePlanActivity 的设计思路如下:
- 使用 LitePal 进行数据库操作:使用 LitePal 简化数据库操作,方便获取和更新用户配置信息。
- 使用 Handler 处理子线程消息:使用 Handler 将子线程中数据下载和解析完成的消息传递给主线程,更新界面状态。
- 使用 ProgressDialog 显示下载进度:使用 ProgressDialog 显示数据下载的进度,提升用户体验。
- 使用 Toast 提示用户:使用 Toast 提示用户设置结果,例如设置成功、设置失败或计划未变。
- 使用 OkHttpClient 进行网络请求:使用 OkHttpClient 进行网络请求,下载单词数据包。
- 使用 FileUtil 和 JsonHelper 进行数据处理:使用 FileUtil 处理文件操作,使用 JsonHelper 解析 JSON 数据。
实现过程和实现思路
以下是对代码中关键部分的实现过程和实现思路进行详细讲解:
1. 初始化控件
在 init() 方法中对界面上的控件进行初始化。
private void init() {
editText = findViewById(R.id.edit_word_num);
textGo = findViewById(R.id.text_plan_next);
textBook = findViewById(R.id.text_plan_chosen);
textWordMaxNum = findViewById(R.id.text_max_word_num);
}
2. 获取用户配置信息
在 onCreate() 方法中获取用户配置信息。
userConfigs = LitePal.where('userId = ?', ConfigData.getSinaNumLogged() + '').find(UserConfig.class);
if (userConfigs.get(0).getWordNeedReciteNum() != 0)
editText.setText(userConfigs.get(0).getWordNeedReciteNum() + '');
3. 设置最大背诵数量和书名
在 onStart() 方法中根据用户配置信息设置最大背诵数量和书名。
maxNum = ConstantData.wordTotalNumberById(currentBookId);
// 设置最大背诵数量
textWordMaxNum.setText(maxNum + '');
// 设置书名
textBook.setText(ConstantData.bookNameById(currentBookId));
4. 更新用户配置信息
在 textGo.setOnClickListener() 中处理用户输入并更新用户配置信息。
textGo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!editText.getText().toString().trim().equals('')) {
if (Integer.parseInt(editText.getText().toString().trim()) >= 5
&& Integer.parseInt(editText.getText().toString().trim()) < maxNum) {
// 隐藏软键盘
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
// 设置数据
// 更新数据
final UserConfig userConfig = new UserConfig();
userConfig.setWordNeedReciteNum(Integer.parseInt(editText.getText().toString().trim()));
userConfig.updateAll('userId = ?', ConfigData.getSinaNumLogged() + '');
// 是第一次设置数据
if (ConfigData.notUpdate == intent.getIntExtra(ConfigData.UPDATE_NAME, 0)) {
// 开启等待框
progressDialog = new ProgressDialog(ChangePlanActivity.this);
progressDialog.setTitle('请稍等');
progressDialog.setMessage('数据包正在下载中...');
progressDialog.setCancelable(false);
progressDialog.show();
// 延迟两秒再运行,防止等待框不显示
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// 开启线程分析数据
thread = new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(ConstantData.bookDownLoadAddressById(currentBookId))
.build();
Response response = client.newCall(request).execute();
Message message = new Message();
message.what = DOWN_DONE;
handler.sendMessage(message);
FileUtil.getFileByBytes(response.body().bytes(), getFilesDir()+ '/' + ConstantData.DIR_TOTAL, ConstantData.bookFileNameById(currentBookId));
FileUtil.unZipFile(getFilesDir()+ '/' + ConstantData.DIR_TOTAL + '/' + ConstantData.bookFileNameById(currentBookId)
, getFilesDir() + '/' + ConstantData.DIR_TOTAL + '/' + ConstantData.DIR_AFTER_FINISH, false);
} catch (Exception e) {
}
JsonHelper.analyseDefaultAndSave(FileUtil.readLocalJson(ConstantData.DIR_TOTAL + '/' + ConstantData.DIR_AFTER_FINISH + '/' + ConstantData.bookFileNameById(currentBookId).replace('.zip', '.json')));
Message message = new Message();
message.what = FINISH;
handler.sendMessage(message);
}
});
thread.start();
}
}, 500);
} else {
if (userConfigs.get(0).getWordNeedReciteNum() != Integer.parseInt(editText.getText().toString().trim())) {
// 重置上次学习时间
UserConfig userConfig1 = new UserConfig();
userConfig1.setLastStartTime(-1);
userConfig1.updateAll('userId = ?', ConfigData.getSinaNumLogged() + '');
Toast.makeText(ChangePlanActivity.this, '' + LitePal.where('userId = ?', ConfigData.getSinaNumLogged() + '').find(UserConfig.class).get(0).getLastStartTime(), Toast.LENGTH_SHORT).show();
Log.d(TAG, 'onClick: ' + LitePal.where('userId = ?', ConfigData.getSinaNumLogged() + '').find(UserConfig.class).get(0).getLastStartTime());
// 删除当天打卡记录
Calendar calendar = Calendar.getInstance();
LitePal.deleteAll(MyDate.class, 'year = ? and month = ? and date = ? and userId = ?'
, calendar.get(Calendar.YEAR) + ''
, (calendar.get(Calendar.MONTH) + 1) + ''
, calendar.get(Calendar.DAY_OF_MONTH) + ''
, ConfigData.getSinaNumLogged() + '');
Toast.makeText(ChangePlanActivity.this, '设置成功', Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ChangePlanActivity.this, '计划未变', Toast.LENGTH_SHORT).show();
}
ActivityCollector.startOtherActivity(ChangePlanActivity.this, MainActivity.class);
}
} else {
Toast.makeText(ChangePlanActivity.this, '请输入合理的范围', Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(ChangePlanActivity.this, '请输入值再继续', Toast.LENGTH_SHORT).show();
}
}
});
5. 跳转到主页面
在 onBackPressed() 方法中处理返回事件,根据用户设置状态跳转到相应的页面。
public void onBackPressed() {
List<UserConfig> userConfigs = LitePal.where('userId = ?', ConfigData.getSinaNumLogged() + '').find(UserConfig.class);
if (userConfigs.get(0).getWordNeedReciteNum() != 0)
super.onBackPressed();
else {
ActivityCollector.startOtherActivity(ChangePlanActivity.this, ChooseWordDBActivity.class);
}
}
总结
ChangePlanActivity 通过简洁的代码和合理的设计,实现了用户修改学习计划的功能,并通过子线程处理数据下载和解析,保证用户体验。代码中使用了 LitePal、Handler、ProgressDialog、Toast、OkHttpClient、FileUtil 和 JsonHelper 等常用的 Android 开发框架和工具,可以作为 Android 开发的参考。
原文地址: https://www.cveoy.top/t/topic/oeaQ 著作权归作者所有。请勿转载和采集!