From 81c2b781b6a7a22e96313f3697d46f4b9204b198 Mon Sep 17 00:00:00 2001 From: Transformers Date: Thu, 21 May 2026 00:12:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=BB=E5=8A=A1=E6=8E=92?= =?UTF-8?q?=E6=A1=A3=E5=8A=9F=E8=83=BD=EF=BC=9A=E6=B7=BB=E5=8A=A0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8C=81=E4=B9=85=E5=8C=96=E3=80=81=E5=A2=9E=E5=88=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=8A=E7=95=8C=E9=9D=A2=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20-=20=E5=8F=96=E6=B6=88=E6=B5=8B=E8=AF=95=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E7=94=A8TaskSchedulerBean=E7=9A=84=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E6=96=B9=E6=B3=95=E5=AE=9E=E7=8E=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=8C=81=E4=B9=85=E5=8C=96=20-=20=E6=B7=BB=E5=8A=A0loadTaskDat?= =?UTF-8?q?a()=E5=92=8CsaveTaskData()=E6=96=B9=E6=B3=95=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=95=B0=E6=8D=AE=E5=8A=A0=E8=BD=BD=E5=92=8C=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=20-=20=E6=B7=BB=E5=8A=A0showAddTaskDialog()=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87=E6=82=AC?= =?UTF-8?q?=E6=B5=AE=E6=8C=89=E9=92=AE=E6=B7=BB=E5=8A=A0=E6=96=B0=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=20-=20=E6=B7=BB=E5=8A=A0showDeleteConfirmDialog()?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E6=94=AF=E6=8C=81=E9=95=BF=E6=8C=89?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=B9=B6=E4=BA=8C=E6=AC=A1=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=20-=20=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4=E5=AF=B9=E8=AF=9D?= =?UTF-8?q?=E6=A1=86=E4=B8=AD=E7=9A=84FrameLayout=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=BC=82=E5=B8=B8=20-=20=E5=9C=A8=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0/=E7=BC=96=E8=BE=91=E4=BB=BB=E5=8A=A1=E5=90=8E?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E4=BF=9D=E5=AD=98=E6=95=B0=E6=8D=AE=20-=20?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E6=96=87=E4=BB=B6=E6=B7=BB=E5=8A=A0=E6=82=AC?= =?UTF-8?q?=E6=B5=AE=E6=B7=BB=E5=8A=A0=E6=8C=89=E9=92=AE=EF=BC=8C=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E4=BD=BF=E7=94=A8=E6=B7=B1=E8=89=B2colorPrimaryDark?= =?UTF-8?q?=20-=20=E8=B0=83=E6=95=B4=E6=A0=B9=E5=B8=83=E5=B1=80=E4=B8=BAFr?= =?UTF-8?q?ameLayout=E4=BB=A5=E6=94=AF=E6=8C=81=E6=82=AC=E6=B5=AE=E6=8C=89?= =?UTF-8?q?=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stallhelper/build.properties | 4 +- .../activities/TaskSchedulerActivity.java | 200 +++++++++++++++++- .../res/layout/activity_task_scheduler.xml | 43 ++-- 3 files changed, 228 insertions(+), 19 deletions(-) diff --git a/stallhelper/build.properties b/stallhelper/build.properties index 6362bd2..037dce0 100644 --- a/stallhelper/build.properties +++ b/stallhelper/build.properties @@ -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 diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/TaskSchedulerActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/TaskSchedulerActivity.java index 9ca3aa2..25afff2 100644 --- a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/TaskSchedulerActivity.java +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/TaskSchedulerActivity.java @@ -57,13 +57,22 @@ public class TaskSchedulerActivity extends WinBoLLActivity { // 初始化任务列表 mTaskList = new ArrayList(); - 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; } }); // 弹出菜单 diff --git a/stallhelper/src/main/res/layout/activity_task_scheduler.xml b/stallhelper/src/main/res/layout/activity_task_scheduler.xml index e0d3475..e99bd0e 100644 --- a/stallhelper/src/main/res/layout/activity_task_scheduler.xml +++ b/stallhelper/src/main/res/layout/activity_task_scheduler.xml @@ -1,22 +1,39 @@ - - + android:layout_height="match_parent" + android:orientation="vertical"> - + - + + + + +