优化任务排档功能:添加数据持久化、增删功能及界面优化

- 取消测试数据,使用TaskSchedulerBean的存储方法实现数据持久化
- 添加loadTaskData()和saveTaskData()方法,实现数据加载和保存
- 添加showAddTaskDialog()方法,支持通过悬浮按钮添加新任务
- 添加showDeleteConfirmDialog()方法,支持长按删除并二次确认
- 修复删除对话框中的FrameLayout强制转换异常
- 在添加/编辑任务后自动保存数据
- 布局文件添加悬浮添加按钮,背景使用深色colorPrimaryDark
- 调整根布局为FrameLayout以支持悬浮按钮
This commit is contained in:
Transformers
2026-05-21 00:12:32 +08:00
parent de63acc114
commit 81c2b781b6
3 changed files with 228 additions and 19 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon May 18 20:16:15 CST 2026
#Thu May 21 00:00:35 CST 2026
stageCount=3
libraryProject=
baseVersion=15.20
publishVersion=15.20.2
buildCount=4
buildCount=11
baseBetaVersion=15.20.3
@@ -57,13 +57,22 @@ public class TaskSchedulerActivity extends WinBoLLActivity {
// 初始化任务列表
mTaskList = new ArrayList<TaskSchedulerBean>();
initSampleData();
loadTaskData();
// 设置 RecyclerView
RecyclerView recyclerView = findViewById(R.id.task_scheduler_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
mAdapter = new TaskSchedulerAdapter(mTaskList);
recyclerView.setAdapter(mAdapter);
// 设置悬浮按钮点击事件
Button fabAddTask = findViewById(R.id.fab_add_task);
fabAddTask.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showAddTaskDialog();
}
});
}
@Override
@@ -74,6 +83,30 @@ public class TaskSchedulerActivity extends WinBoLLActivity {
return super.onOptionsItemSelected(item);
}
/**
* 从文件加载任务数据
*/
private void loadTaskData() {
boolean loadSuccess = TaskSchedulerBean.loadBeanList(this, mTaskList, TaskSchedulerBean.class);
if (loadSuccess) {
LogUtils.i(TAG, "loadTaskData: 成功加载 " + mTaskList.size() + " 条任务数据");
} else {
LogUtils.i(TAG, "loadTaskData: 未找到已保存的任务数据,使用空列表");
}
}
/**
* 保存任务数据到文件
*/
private void saveTaskData() {
boolean saveSuccess = TaskSchedulerBean.saveBeanList(this, mTaskList, TaskSchedulerBean.class);
if (saveSuccess) {
LogUtils.i(TAG, "saveTaskData: 成功保存 " + mTaskList.size() + " 条任务数据");
} else {
LogUtils.e(TAG, "saveTaskData: 任务数据保存失败");
}
}
/**
* 格式化时间戳为年月日和小时
* @param timestamp 时间戳
@@ -279,6 +312,7 @@ public class TaskSchedulerActivity extends WinBoLLActivity {
task.setRemark(remark);
mAdapter.notifyItemChanged(position);
saveTaskData();
LogUtils.i(TAG, "showEditTaskDialog: 任务 [" + taskName + "] 数据已更新,排档幅度=" + durationMinutes + "分钟");
dialog.dismiss();
}
@@ -286,6 +320,157 @@ public class TaskSchedulerActivity extends WinBoLLActivity {
dialog.show();
}
/**
* 显示添加任务对话框
*/
private void showAddTaskDialog() {
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_task_edit);
final EditText etTaskName = dialog.findViewById(R.id.dialog_et_task_name);
final EditText etCurrentScheduleTime = dialog.findViewById(R.id.dialog_et_start_time);
final EditText etMonth = dialog.findViewById(R.id.dialog_et_month);
final EditText etDay = dialog.findViewById(R.id.dialog_et_day);
final EditText etHour = dialog.findViewById(R.id.dialog_et_hour);
final EditText etRemark = dialog.findViewById(R.id.dialog_et_remark);
Button btnCancel = dialog.findViewById(R.id.dialog_btn_cancel);
Button btnSave = dialog.findViewById(R.id.dialog_btn_save);
// 设置默认时间为当前时间
java.util.Calendar calendar = java.util.Calendar.getInstance();
calendar.set(java.util.Calendar.MINUTE, 0);
calendar.set(java.util.Calendar.SECOND, 0);
calendar.set(java.util.Calendar.MILLISECOND, 0);
etCurrentScheduleTime.setText(formatTimestamp(calendar.getTimeInMillis()));
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String taskName = etTaskName.getText().toString().trim();
String currentScheduleTime = etCurrentScheduleTime.getText().toString().trim();
String monthStr = etMonth.getText().toString().trim();
String dayStr = etDay.getText().toString().trim();
String hourStr = etHour.getText().toString().trim();
String remark = etRemark.getText().toString().trim();
if (taskName.isEmpty()) {
etTaskName.setError("请输入任务名称");
return;
}
if (currentScheduleTime.isEmpty()) {
etCurrentScheduleTime.setError("请输入当前排档时间");
return;
}
long timestamp = parseTimeString(currentScheduleTime);
if (timestamp == 0) {
etCurrentScheduleTime.setError("时间格式不正确,请使用 yyyy-MM-dd HH 格式");
return;
}
int month = 0, day = 0, hour = 0;
try {
if (!monthStr.isEmpty()) month = Integer.parseInt(monthStr);
if (!dayStr.isEmpty()) day = Integer.parseInt(dayStr);
if (!hourStr.isEmpty()) hour = Integer.parseInt(hourStr);
} catch (NumberFormatException e) {
LogUtils.e(TAG, "showAddTaskDialog: 数字解析错误", e);
return;
}
int durationMinutes = convertToTotalMinutes(month, day, hour);
TaskSchedulerBean newTask = new TaskSchedulerBean(taskName, remark, timestamp, durationMinutes);
mTaskList.add(newTask);
mAdapter.notifyItemInserted(mTaskList.size() - 1);
saveTaskData();
LogUtils.i(TAG, "showAddTaskDialog: 任务 [" + taskName + "] 已添加,排档幅度=" + durationMinutes + "分钟");
dialog.dismiss();
}
});
dialog.show();
}
/**
* 显示删除确认对话框
* @param position 要删除的任务位置
*/
private void showDeleteConfirmDialog(final int position) {
if (position < 0 || position >= mTaskList.size()) {
return;
}
final TaskSchedulerBean task = mTaskList.get(position);
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_task_edit);
// 修改对话框布局,只保留必要的按钮
// 隐藏不需要的视图
android.view.View etTaskName = dialog.findViewById(R.id.dialog_et_task_name);
android.view.View etCurrentScheduleTime = dialog.findViewById(R.id.dialog_et_start_time);
android.view.View etMonth = dialog.findViewById(R.id.dialog_et_month);
android.view.View etDay = dialog.findViewById(R.id.dialog_et_day);
android.view.View etHour = dialog.findViewById(R.id.dialog_et_hour);
android.view.View etRemark = dialog.findViewById(R.id.dialog_et_remark);
if (etTaskName != null) etTaskName.setVisibility(View.GONE);
if (etCurrentScheduleTime != null) etCurrentScheduleTime.setVisibility(View.GONE);
if (etMonth != null) etMonth.setVisibility(View.GONE);
if (etDay != null) etDay.setVisibility(View.GONE);
if (etHour != null) etHour.setVisibility(View.GONE);
if (etRemark != null) etRemark.setVisibility(View.GONE);
// 添加提示文本
android.widget.TextView tvMessage = new android.widget.TextView(this);
tvMessage.setText("确定要删除任务 \"" + task.getTaskName() + "\" 吗?");
tvMessage.setPadding(40, 40, 40, 20);
tvMessage.setTextSize(16);
android.view.ViewGroup rootView = dialog.findViewById(android.R.id.content);
if (rootView != null) {
android.view.ViewGroup.LayoutParams params = new android.view.ViewGroup.LayoutParams(
android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.WRAP_CONTENT
);
rootView.addView(tvMessage, 0, params);
}
Button btnCancel = dialog.findViewById(R.id.dialog_btn_cancel);
Button btnSave = dialog.findViewById(R.id.dialog_btn_save);
if (btnSave != null) {
btnSave.setText("确定删除");
}
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String taskName = task.getTaskName();
mTaskList.remove(position);
mAdapter.notifyItemRemoved(position);
saveTaskData();
LogUtils.i(TAG, "showDeleteConfirmDialog: 任务 [" + taskName + "] 已删除");
dialog.dismiss();
}
});
dialog.show();
}
/**
* 执行排档操作
* @param position 点击排档按钮的任务位置
@@ -340,12 +525,19 @@ public class TaskSchedulerActivity extends WinBoLLActivity {
// 使用PopupMenu替代ContextMenu
PopupMenu popup = new PopupMenu(TaskSchedulerActivity.this, v);
popup.getMenu().add("编辑任务内容");
popup.getMenu().add("删除任务");
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// 直接使用onBind里的position,无需取tag
showEditTaskDialog(position);
return true;
String title = item.getTitle().toString();
if ("编辑任务内容".equals(title)) {
showEditTaskDialog(position);
return true;
} else if ("删除任务".equals(title)) {
showDeleteConfirmDialog(position);
return true;
}
return false;
}
});
// 弹出菜单
@@ -1,22 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="?attr/activityBackgroundColor">
<androidx.appcompat.widget.Toolbar
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/toolbarBackgroundColor"
android:id="@+id/toolbar"/>
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp"
android:id="@+id/task_scheduler_recycler_view"/>
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/toolbarBackgroundColor"
android:id="@+id/toolbar"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp"
android:id="@+id/task_scheduler_recycler_view"/>
</LinearLayout>
<Button
android:id="@+id/fab_add_task"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:background="@color/colorPrimaryDark"
android:text="+"
android:textColor="@android:color/white"
android:textSize="24sp"/>
</FrameLayout>