mirror of
https://gitea.winboll.cc/ZhanGSKen/MyWinBoLL.git
synced 2026-08-22 17:05:51 +08:00
Merge branch 'stallhelper' into merge
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Wed May 13 02:22:06 HKT 2026
|
||||
stageCount=2
|
||||
#Fri May 22 20:27:28 HKT 2026
|
||||
stageCount=9
|
||||
libraryProject=
|
||||
baseVersion=15.20
|
||||
publishVersion=15.20.1
|
||||
publishVersion=15.20.8
|
||||
buildCount=0
|
||||
baseBetaVersion=15.20.2
|
||||
baseBetaVersion=15.20.9
|
||||
|
||||
@@ -42,8 +42,10 @@
|
||||
android:name="cc.winboll.studio.stallhelper.activities.CompleteDiningTableActivity"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity android:name="cc.winboll.studio.stallhelper.activities.NoteRecordHelperActivity"/>
|
||||
<activity android:name="cc.winboll.studio.stallhelper.activities.NoteRecordHelperActivity"/>
|
||||
|
||||
</application>
|
||||
<activity android:name="cc.winboll.studio.stallhelper.activities.TaskSchedulerActivity"/>
|
||||
|
||||
</manifest>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -8,6 +8,7 @@ package cc.winboll.studio.stallhelper;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.libappbase.BuildConfig;
|
||||
|
||||
public class App extends GlobalApplication {
|
||||
|
||||
@@ -17,8 +18,9 @@ public class App extends GlobalApplication {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
super.onCreate();
|
||||
setIsDebugging(BuildConfig.DEBUG);
|
||||
if (isDebugging() != true) {
|
||||
setIsDebugging(BuildConfig.DEBUG);
|
||||
}
|
||||
//setIsDebugging(false);
|
||||
WinBoLLActivityManager.init(this);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import cc.winboll.studio.stallhelper.activities.AboutActivity;
|
||||
import cc.winboll.studio.stallhelper.activities.CompleteDiningTableActivity;
|
||||
import cc.winboll.studio.stallhelper.activities.NoteRecordHelperActivity;
|
||||
import cc.winboll.studio.stallhelper.activities.PreNullDiningTableActivity;
|
||||
import cc.winboll.studio.stallhelper.activities.TaskSchedulerActivity;
|
||||
import cc.winboll.studio.stallhelper.activities.WinBoLLActivity;
|
||||
|
||||
final public class MainActivity extends WinBoLLActivity {
|
||||
@@ -126,4 +127,9 @@ final public class MainActivity extends WinBoLLActivity {
|
||||
Intent intent = new Intent(getApplicationContext(), NoteRecordHelperActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public void onTaskScheduler(View view) {
|
||||
Intent intent = new Intent(getApplicationContext(), TaskSchedulerActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
+766
@@ -0,0 +1,766 @@
|
||||
package cc.winboll.studio.stallhelper.activities;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.stallhelper.R;
|
||||
import cc.winboll.studio.stallhelper.beans.TaskSchedulerBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import net.sourceforge.pinyin4j.PinyinHelper;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen
|
||||
* @Date 2026/05/18
|
||||
* @Describe 任务排档窗口
|
||||
*/
|
||||
public class TaskSchedulerActivity extends WinBoLLActivity {
|
||||
|
||||
public static final String TAG = "TaskSchedulerActivity";
|
||||
|
||||
// 时间转换常量
|
||||
private static final int MINUTES_PER_HOUR = 60;
|
||||
private static final int HOURS_PER_DAY = 24;
|
||||
private static final int DAYS_PER_MONTH = 30; // 默认按30天计算
|
||||
|
||||
ArrayList<TaskSchedulerBean> mTaskList;
|
||||
TaskSchedulerAdapter mAdapter;
|
||||
EditText mSearchEditText;
|
||||
String mSearchQuery = "";
|
||||
HanyuPinyinOutputFormat mPinyinFormat;
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_task_scheduler);
|
||||
LogUtils.i(TAG, "onCreate: 任务排档页面初始化");
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
setTitle("任务排档");
|
||||
|
||||
// 初始化任务列表
|
||||
mTaskList = new ArrayList<TaskSchedulerBean>();
|
||||
loadTaskData();
|
||||
|
||||
// 设置搜索框
|
||||
mPinyinFormat = new HanyuPinyinOutputFormat();
|
||||
mPinyinFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||
mPinyinFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||
|
||||
mSearchEditText = findViewById(R.id.et_search);
|
||||
mSearchEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
mSearchQuery = s.toString().trim().toLowerCase();
|
||||
filterTaskList();
|
||||
}
|
||||
});
|
||||
|
||||
// 设置 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
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
WinBoLLActivityManager.getInstance().finish(this);
|
||||
}
|
||||
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: 未找到已保存的任务数据,使用空列表");
|
||||
}
|
||||
sortTaskList();
|
||||
}
|
||||
|
||||
private void applyChanges() {
|
||||
sortTaskList();
|
||||
filterTaskList();
|
||||
saveTaskData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存任务数据到文件
|
||||
*/
|
||||
private void saveTaskData() {
|
||||
boolean saveSuccess = TaskSchedulerBean.saveBeanList(this, mTaskList, TaskSchedulerBean.class);
|
||||
if (saveSuccess) {
|
||||
LogUtils.i(TAG, "saveTaskData: 成功保存 " + mTaskList.size() + " 条任务数据");
|
||||
} else {
|
||||
LogUtils.e(TAG, "saveTaskData: 任务数据保存失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按排档时间倒序排列列表
|
||||
*/
|
||||
private void sortTaskList() {
|
||||
Collections.sort(mTaskList, new Comparator<TaskSchedulerBean>() {
|
||||
@Override
|
||||
public int compare(TaskSchedulerBean a, TaskSchedulerBean b) {
|
||||
long diff = a.getCurrentScheduleTime() - b.getCurrentScheduleTime();
|
||||
if (diff > 0) return 1;
|
||||
if (diff < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间戳为年月日和小时
|
||||
* @param timestamp 时间戳
|
||||
* @return 格式化的时间字符串,如 "2026-05-18 09"
|
||||
*/
|
||||
private String formatTimestamp(long timestamp) {
|
||||
if (timestamp == 0) {
|
||||
return "";
|
||||
}
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH");
|
||||
java.util.Date date = new java.util.Date(timestamp);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析时间字符串为时间戳
|
||||
* @param timeStr 时间字符串,如 "2026-05-18 09"
|
||||
* @return 时间戳
|
||||
*/
|
||||
private long parseTimeString(String timeStr) {
|
||||
if (timeStr == null || timeStr.trim().isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH");
|
||||
java.util.Date date = sdf.parse(timeStr);
|
||||
return date.getTime();
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "parseTimeString: 时间解析错误", e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化示例数据
|
||||
*/
|
||||
private void initSampleData() {
|
||||
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);
|
||||
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 9);
|
||||
long time9 = calendar.getTimeInMillis();
|
||||
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 10);
|
||||
long time10 = calendar.getTimeInMillis();
|
||||
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 11);
|
||||
calendar.set(java.util.Calendar.MINUTE, 30);
|
||||
long time1130 = calendar.getTimeInMillis();
|
||||
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 12);
|
||||
calendar.set(java.util.Calendar.MINUTE, 30);
|
||||
long time1230 = calendar.getTimeInMillis();
|
||||
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 16);
|
||||
calendar.set(java.util.Calendar.MINUTE, 0);
|
||||
long time16 = calendar.getTimeInMillis();
|
||||
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 17);
|
||||
long time17 = calendar.getTimeInMillis();
|
||||
|
||||
mTaskList.add(new TaskSchedulerBean("准备食材", "购买新鲜蔬菜和肉类", time9, 60));
|
||||
mTaskList.add(new TaskSchedulerBean("烹饪午餐", "按照食谱准备午餐", time10, 90));
|
||||
mTaskList.add(new TaskSchedulerBean("用餐休息", "享受美食并休息", time1130, 60));
|
||||
mTaskList.add(new TaskSchedulerBean("清洁厨房", "清洗餐具和整理厨房", time1230, 45));
|
||||
mTaskList.add(new TaskSchedulerBean("准备晚餐", "提前准备晚餐食材", time16, 60));
|
||||
mTaskList.add(new TaskSchedulerBean("烹饪晚餐", "制作丰盛的晚餐", time17, 90));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将中文转换为拼音(不含声调,小写)
|
||||
*/
|
||||
private String toPinyin(String chinese) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < chinese.length(); i++) {
|
||||
char c = chinese.charAt(i);
|
||||
try {
|
||||
String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c, mPinyinFormat);
|
||||
if (pinyins != null && pinyins.length > 0) {
|
||||
sb.append(pinyins[0]);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将中文转换为拼音首字母串(小写)
|
||||
*/
|
||||
private String toPinyinInitials(String chinese) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < chinese.length(); i++) {
|
||||
char c = chinese.charAt(i);
|
||||
try {
|
||||
String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c, mPinyinFormat);
|
||||
if (pinyins != null && pinyins.length > 0) {
|
||||
sb.append(pinyins[0].charAt(0));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查任务名称是否匹配搜索关键词(支持中文/拼音/首字母)
|
||||
*/
|
||||
private boolean matchesSearch(TaskSchedulerBean task, String query) {
|
||||
if (query == null || query.isEmpty()) return true;
|
||||
String name = task.getTaskName();
|
||||
if (name == null) return false;
|
||||
if (name.toLowerCase().contains(query)) return true;
|
||||
String pinyin = toPinyin(name);
|
||||
if (pinyin.contains(query)) return true;
|
||||
String initials = toPinyinInitials(name);
|
||||
if (initials.contains(query)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据搜索关键词过滤任务列表并刷新界面
|
||||
*/
|
||||
private void filterTaskList() {
|
||||
if (mSearchQuery.isEmpty()) {
|
||||
mAdapter.setData(mTaskList);
|
||||
return;
|
||||
}
|
||||
ArrayList<TaskSchedulerBean> filteredList = new ArrayList<TaskSchedulerBean>();
|
||||
for (TaskSchedulerBean task : mTaskList) {
|
||||
if (matchesSearch(task, mSearchQuery)) {
|
||||
filteredList.add(task);
|
||||
}
|
||||
}
|
||||
mAdapter.setData(filteredList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将月、天、小时转换为总分钟数
|
||||
* @param month 月份
|
||||
* @param day 天数
|
||||
* @param hour 小时
|
||||
* @return 总分钟数
|
||||
*/
|
||||
private int convertToTotalMinutes(int month, int day, int hour) {
|
||||
return month * DAYS_PER_MONTH * HOURS_PER_DAY * MINUTES_PER_HOUR +
|
||||
day * HOURS_PER_DAY * MINUTES_PER_HOUR +
|
||||
hour * MINUTES_PER_HOUR;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将总分钟数转换为月、天、小时的格式字符串
|
||||
* @param totalMinutes 总分钟数
|
||||
* @return 格式化的字符串,如 "0月0天1小时"
|
||||
*/
|
||||
private String formatDurationToString(int totalMinutes) {
|
||||
int totalHours = totalMinutes / MINUTES_PER_HOUR;
|
||||
int totalDays = totalHours / HOURS_PER_DAY;
|
||||
int month = totalDays / DAYS_PER_MONTH;
|
||||
int day = totalDays % DAYS_PER_MONTH;
|
||||
int hour = totalHours % HOURS_PER_DAY;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (month > 0) {
|
||||
sb.append(month).append("月");
|
||||
}
|
||||
if (day > 0) {
|
||||
sb.append(day).append("天");
|
||||
}
|
||||
if (hour > 0) {
|
||||
sb.append(hour).append("小时");
|
||||
}
|
||||
if (sb.length() == 0) {
|
||||
sb.append("0小时");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示编辑任务对话框
|
||||
* @param position 要编辑的任务位置
|
||||
*/
|
||||
private void showEditTaskDialog(final int position) {
|
||||
if (position < 0 || position >= mAdapter.mDataList.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TaskSchedulerBean task = mAdapter.mDataList.get(position);
|
||||
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);
|
||||
Button btnNow = dialog.findViewById(R.id.dialog_btn_now);
|
||||
|
||||
etTaskName.setText(task.getTaskName());
|
||||
etCurrentScheduleTime.setText(formatTimestamp(task.getCurrentScheduleTime()));
|
||||
etRemark.setText(task.getRemark());
|
||||
|
||||
int totalMinutes = task.getDurationMinutes();
|
||||
int totalHours = totalMinutes / MINUTES_PER_HOUR;
|
||||
int totalDays = totalHours / HOURS_PER_DAY;
|
||||
int month = totalDays / DAYS_PER_MONTH;
|
||||
int day = totalDays % DAYS_PER_MONTH;
|
||||
int hour = totalHours % HOURS_PER_DAY;
|
||||
|
||||
if (month > 0) {
|
||||
etMonth.setText(Integer.toString(month));
|
||||
}
|
||||
if (day > 0) {
|
||||
etDay.setText(Integer.toString(day));
|
||||
}
|
||||
if (hour > 0) {
|
||||
etHour.setText(Integer.toString(hour));
|
||||
}
|
||||
|
||||
btnNow.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
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, "showEditTaskDialog: 数字解析错误", e);
|
||||
return;
|
||||
}
|
||||
|
||||
int durationMinutes = convertToTotalMinutes(month, day, hour);
|
||||
task.setTaskName(taskName);
|
||||
task.setCurrentScheduleTime(timestamp);
|
||||
task.setDurationMinutes(durationMinutes);
|
||||
task.setRemark(remark);
|
||||
|
||||
applyChanges();
|
||||
LogUtils.i(TAG, "showEditTaskDialog: 任务 [" + taskName + "] 数据已更新,排档幅度=" + durationMinutes + "分钟");
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
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);
|
||||
Button btnNow = dialog.findViewById(R.id.dialog_btn_now);
|
||||
|
||||
// 设置默认时间为当前时间
|
||||
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()));
|
||||
|
||||
btnNow.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
java.util.Calendar cal = java.util.Calendar.getInstance();
|
||||
cal.set(java.util.Calendar.MINUTE, 0);
|
||||
cal.set(java.util.Calendar.SECOND, 0);
|
||||
cal.set(java.util.Calendar.MILLISECOND, 0);
|
||||
etCurrentScheduleTime.setText(formatTimestamp(cal.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);
|
||||
applyChanges();
|
||||
LogUtils.i(TAG, "showAddTaskDialog: 任务 [" + taskName + "] 已添加,排档幅度=" + durationMinutes + "分钟");
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示删除确认对话框
|
||||
* @param position 要删除的任务位置
|
||||
*/
|
||||
private void showDeleteConfirmDialog(final int position) {
|
||||
if (position < 0 || position >= mAdapter.mDataList.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TaskSchedulerBean task = mAdapter.mDataList.get(position);
|
||||
final Dialog dialog = new Dialog(this);
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(R.layout.dialog_delete_confirm);
|
||||
|
||||
TextView tvMessage = dialog.findViewById(R.id.dialog_delete_message);
|
||||
Button btnCancel = dialog.findViewById(R.id.dialog_btn_cancel);
|
||||
Button btnConfirm = dialog.findViewById(R.id.dialog_btn_confirm);
|
||||
|
||||
tvMessage.setText("确定要删除任务 \"" + task.getTaskName() + "\" 吗?");
|
||||
|
||||
btnCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
btnConfirm.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String taskName = task.getTaskName();
|
||||
mTaskList.remove(task);
|
||||
applyChanges();
|
||||
LogUtils.i(TAG, "showDeleteConfirmDialog: 任务 [" + taskName + "] 已删除");
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示排档确认对话框
|
||||
* @param position 要排档的任务位置
|
||||
*/
|
||||
private void showScheduleConfirmDialog(final int position) {
|
||||
if (position < 0 || position >= mAdapter.mDataList.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TaskSchedulerBean task = mAdapter.mDataList.get(position);
|
||||
long currentTime = task.getCurrentScheduleTime();
|
||||
int duration = task.getDurationMinutes();
|
||||
long newTime = currentTime + duration * 60 * 1000L;
|
||||
|
||||
final Dialog dialog = new Dialog(this);
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(R.layout.dialog_schedule_confirm);
|
||||
|
||||
TextView tvTaskName = dialog.findViewById(R.id.dialog_schedule_task_name);
|
||||
TextView tvCurrentTime = dialog.findViewById(R.id.dialog_schedule_current_time);
|
||||
TextView tvDuration = dialog.findViewById(R.id.dialog_schedule_duration);
|
||||
TextView tvRemark = dialog.findViewById(R.id.dialog_schedule_remark);
|
||||
TextView tvNewTime = dialog.findViewById(R.id.dialog_schedule_new_time);
|
||||
Button btnCancel = dialog.findViewById(R.id.dialog_btn_cancel);
|
||||
Button btnConfirm = dialog.findViewById(R.id.dialog_btn_confirm);
|
||||
|
||||
tvTaskName.setText("任务:" + task.getTaskName());
|
||||
tvCurrentTime.setText("当前排档时间:" + formatTimestamp(currentTime));
|
||||
tvDuration.setText("排档幅度:" + formatDurationToString(duration));
|
||||
tvRemark.setText("备注:" + (task.getRemark() != null && !task.getRemark().isEmpty() ? task.getRemark() : "无"));
|
||||
tvNewTime.setText("排档后时间:" + formatTimestamp(newTime));
|
||||
|
||||
btnCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
btnConfirm.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dialog.dismiss();
|
||||
performSchedule(position);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行排档操作
|
||||
* @param position 点击排档按钮的任务位置
|
||||
*/
|
||||
private void performSchedule(int position) {
|
||||
if (position < 0 || position >= mAdapter.mDataList.size()) {
|
||||
return;
|
||||
}
|
||||
TaskSchedulerBean currentTask = mAdapter.mDataList.get(position);
|
||||
long currentTime = currentTask.getCurrentScheduleTime();
|
||||
int duration = currentTask.getDurationMinutes();
|
||||
long newTime = currentTime + duration * 60 * 1000L;
|
||||
LogUtils.i(TAG, "performSchedule: 当前时间 " + formatTimestamp(currentTime) + " + " + duration + "分钟 = " + formatTimestamp(newTime));
|
||||
currentTask.setCurrentScheduleTime(newTime);
|
||||
applyChanges();
|
||||
LogUtils.i(TAG, "performSchedule: 更新任务 [" + currentTask.getTaskName() + "] 时间更新为 " + formatTimestamp(newTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* RecyclerView 适配器
|
||||
*/
|
||||
class TaskSchedulerAdapter extends RecyclerView.Adapter {
|
||||
|
||||
ArrayList<TaskSchedulerBean> mDataList;
|
||||
|
||||
public TaskSchedulerAdapter(ArrayList<TaskSchedulerBean> dataList) {
|
||||
mDataList = dataList;
|
||||
}
|
||||
|
||||
public void setData(ArrayList<TaskSchedulerBean> dataList) {
|
||||
mDataList = dataList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mDataList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
|
||||
final TaskSchedulerBean item = mDataList.get(position);
|
||||
final TaskViewHolder viewHolder = (TaskViewHolder) holder;
|
||||
|
||||
viewHolder.mtvTaskName.setText(item.getTaskName());
|
||||
viewHolder.mtvCurrentScheduleTime.setText(formatTimestamp(item.getCurrentScheduleTime()));
|
||||
viewHolder.mtvDuration.setText(formatDurationToString(item.getDurationMinutes()));
|
||||
viewHolder.mtvRemark.setText(item.getRemark());
|
||||
|
||||
long diffMs = item.getCurrentScheduleTime() - System.currentTimeMillis();
|
||||
int diffMinutes = (int) Math.abs(diffMs / 60000);
|
||||
if (diffMs >= 0) {
|
||||
viewHolder.mtvTimeDiff.setText("剩余" + formatDurationToString(diffMinutes));
|
||||
} else {
|
||||
viewHolder.mtvTimeDiff.setText("已过" + formatDurationToString(diffMinutes));
|
||||
}
|
||||
|
||||
if (item.getCurrentScheduleTime() <= System.currentTimeMillis()) {
|
||||
viewHolder.mllMain.setBackgroundResource(R.color.colorScheduleFutureBackground);
|
||||
} else {
|
||||
viewHolder.mllMain.setBackgroundResource(R.drawable.bg_frame);
|
||||
}
|
||||
|
||||
// 长按直接内置菜单,直接使用当前position
|
||||
viewHolder.mllMain.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(final View v) {
|
||||
// 使用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) {
|
||||
String title = item.getTitle().toString();
|
||||
if ("编辑任务内容".equals(title)) {
|
||||
showEditTaskDialog(position);
|
||||
return true;
|
||||
} else if ("删除任务".equals(title)) {
|
||||
showDeleteConfirmDialog(position);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// 弹出菜单
|
||||
popup.show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.mbtnSchedule.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showScheduleConfirmDialog(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_task_scheduler, parent, false);
|
||||
return new TaskViewHolder(view);
|
||||
}
|
||||
|
||||
class TaskViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView mtvTaskName;
|
||||
TextView mtvCurrentScheduleTime;
|
||||
TextView mtvTimeDiff;
|
||||
TextView mtvDuration;
|
||||
TextView mtvRemark;
|
||||
LinearLayout mllMain;
|
||||
Button mbtnSchedule;
|
||||
|
||||
TaskViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
mtvTaskName = itemView.findViewById(R.id.item_task_name);
|
||||
mtvCurrentScheduleTime = itemView.findViewById(R.id.item_start_time);
|
||||
mtvTimeDiff = itemView.findViewById(R.id.item_time_diff);
|
||||
mtvDuration = itemView.findViewById(R.id.item_duration);
|
||||
mtvRemark = itemView.findViewById(R.id.item_remark);
|
||||
mllMain = itemView.findViewById(R.id.itemtaskscheduler_llmain);
|
||||
mbtnSchedule = itemView.findViewById(R.id.item_btn_schedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package cc.winboll.studio.stallhelper.beans;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen
|
||||
* @Date 2026/05/18
|
||||
* @Describe 任务排档数据模型
|
||||
*/
|
||||
import android.util.JsonReader;
|
||||
import android.util.JsonWriter;
|
||||
import cc.winboll.studio.libappbase.BaseBean;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TaskSchedulerBean extends BaseBean {
|
||||
|
||||
public static final String TAG = "TaskSchedulerBean";
|
||||
|
||||
// 任务排档名称
|
||||
String taskName;
|
||||
// 备注
|
||||
String remark;
|
||||
// 当前排档时间(时间戳)
|
||||
long currentScheduleTime;
|
||||
// 排档时间幅度(分钟)- 用于计算下一个任务的起始时间
|
||||
int durationMinutes;
|
||||
|
||||
public TaskSchedulerBean() {
|
||||
this.taskName = "";
|
||||
this.remark = "";
|
||||
this.currentScheduleTime = 0;
|
||||
this.durationMinutes = 0;
|
||||
}
|
||||
|
||||
public TaskSchedulerBean(String taskName, String remark, long currentScheduleTime, int durationMinutes) {
|
||||
this.taskName = taskName;
|
||||
this.remark = remark;
|
||||
this.currentScheduleTime = currentScheduleTime;
|
||||
this.durationMinutes = durationMinutes;
|
||||
}
|
||||
|
||||
public String getTaskName() {
|
||||
return taskName;
|
||||
}
|
||||
|
||||
public void setTaskName(String taskName) {
|
||||
this.taskName = taskName;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public long getCurrentScheduleTime() {
|
||||
return currentScheduleTime;
|
||||
}
|
||||
|
||||
public void setCurrentScheduleTime(long currentScheduleTime) {
|
||||
this.currentScheduleTime = currentScheduleTime;
|
||||
}
|
||||
|
||||
public int getDurationMinutes() {
|
||||
return durationMinutes;
|
||||
}
|
||||
|
||||
public void setDurationMinutes(int durationMinutes) {
|
||||
this.durationMinutes = durationMinutes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return TaskSchedulerBean.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
|
||||
super.writeThisToJsonWriter(jsonWriter);
|
||||
TaskSchedulerBean bean = this;
|
||||
jsonWriter.name("taskName").value(bean.getTaskName());
|
||||
jsonWriter.name("remark").value(bean.getRemark());
|
||||
jsonWriter.name("startTime").value(bean.getCurrentScheduleTime());
|
||||
jsonWriter.name("durationMinutes").value(bean.getDurationMinutes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
|
||||
if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else {
|
||||
if (name.equals("taskName")) {
|
||||
setTaskName(jsonReader.nextString());
|
||||
} else if (name.equals("remark")) {
|
||||
setRemark(jsonReader.nextString());
|
||||
} else if (name.equals("startTime")) {
|
||||
setCurrentScheduleTime(jsonReader.nextLong());
|
||||
} else if (name.equals("durationMinutes")) {
|
||||
setDurationMinutes(jsonReader.nextInt());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskSchedulerBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
|
||||
jsonReader.beginObject();
|
||||
while (jsonReader.hasNext()) {
|
||||
String name = jsonReader.nextName();
|
||||
if (!initObjectsFromJsonReader(jsonReader, name)) {
|
||||
jsonReader.skipValue();
|
||||
}
|
||||
}
|
||||
jsonReader.endObject();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="256">
|
||||
<!-- 背景圆形 -->
|
||||
<path
|
||||
android:fillColor="#FF4CAF50"
|
||||
android:strokeColor="#FF4CAF50"
|
||||
android:strokeWidth="2.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M128,44 C81.4,44 44,81.4 44,128 C44,174.6 81.4,212 128,212 C174.6,212 212,174.6 212,128 C212,81.4 174.6,44 128,44 Z"/>
|
||||
<!-- 文档/列表背景 -->
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:strokeColor="#FFFFFFFF"
|
||||
android:strokeWidth="2.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M85,80 L171,80 L171,180 L85,180 L85,80 Z"/>
|
||||
<!-- 列表线1 -->
|
||||
<path
|
||||
android:fillColor="#FF333333"
|
||||
android:strokeColor="#FF333333"
|
||||
android:strokeWidth="4.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M100,100 L156,100"/>
|
||||
<!-- 列表线2 -->
|
||||
<path
|
||||
android:fillColor="#FF333333"
|
||||
android:strokeColor="#FF333333"
|
||||
android:strokeWidth="4.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M100,120 L156,120"/>
|
||||
<!-- 列表线3 -->
|
||||
<path
|
||||
android:fillColor="#FF333333"
|
||||
android:strokeColor="#FF333333"
|
||||
android:strokeWidth="4.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M100,140 L156,140"/>
|
||||
<!-- 勾选标记 -->
|
||||
<path
|
||||
android:fillColor="#FF4CAF50"
|
||||
android:strokeColor="#FF4CAF50"
|
||||
android:strokeWidth="4.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M95,98 L101,104 L115,90"/>
|
||||
<!-- 时钟指针暗示 -->
|
||||
<path
|
||||
android:fillColor="#FF4CAF50"
|
||||
android:strokeColor="#FF4CAF50"
|
||||
android:strokeWidth="4.0"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeMiterLimit="10"
|
||||
android:pathData="M128,150 L128,168 L144,168"/>
|
||||
</vector>
|
||||
@@ -67,30 +67,53 @@
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_frame"
|
||||
android:onClick="onNoteRecordHelper">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_frame"
|
||||
android:onClick="onNoteRecordHelper">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/colorCompleteBackgroung"
|
||||
android:src="@drawable/ic_noterecordhelper"
|
||||
android:layout_margin="10dp"/>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/colorCompleteBackgroung"
|
||||
android:src="@drawable/ic_noterecordhelper"
|
||||
android:layout_margin="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="订单笔录辅助"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="订单笔录辅助"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_frame"
|
||||
android:onClick="onTaskScheduler">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/colorPreNullBackgroung"
|
||||
android:src="@drawable/ic_task_scheduler"
|
||||
android:layout_margin="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="任务排档"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/activityBackgroundColor">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/toolbarBackgroundColor"
|
||||
android:id="@+id/toolbar"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_search"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="搜索任务名称(支持中文/拼音)"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:layout_margin="10dp"
|
||||
android:inputType="text"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<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>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:background="?android:attr/windowBackground">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确认删除"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="15dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_delete_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:paddingBottom="20dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end">
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="取消"
|
||||
android:layout_marginEnd="10dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_confirm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确定删除"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:background="?android:attr/windowBackground">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确认执行排档"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="15dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_schedule_task_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:paddingBottom="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:paddingBottom="5dp"
|
||||
android:id="@+id/dialog_schedule_current_time"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:paddingBottom="5dp"
|
||||
android:id="@+id/dialog_schedule_duration"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:paddingBottom="5dp"
|
||||
android:id="@+id/dialog_schedule_remark"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:paddingTop="10dp"
|
||||
android:textStyle="bold"
|
||||
android:id="@+id/dialog_schedule_new_time"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="20dp"
|
||||
android:gravity="end">
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="取消"
|
||||
android:layout_marginEnd="10dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_confirm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确认排档"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:background="?android:attr/windowBackground">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="编辑任务排档"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="15dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="任务名称:"
|
||||
android:textSize="14sp"
|
||||
android:paddingBottom="5dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_task_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入任务名称"
|
||||
android:inputType="text"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="当前排档时间(yyyy-MM-dd HH):"
|
||||
android:textSize="14sp"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingBottom="5dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_start_time"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="例如:09:00"
|
||||
android:inputType="time"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_now"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="现在"
|
||||
android:layout_marginStart="10dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="排档幅度:"
|
||||
android:textSize="14sp"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingBottom="5dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_month"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="月份"
|
||||
android:inputType="number"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:layout_marginEnd="5dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="月"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_day"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="天数"
|
||||
android:inputType="number"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="5dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="天"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_hour"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="小时"
|
||||
android:inputType="number"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:layout_marginStart="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="小时"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="备注:"
|
||||
android:textSize="14sp"
|
||||
android:paddingTop="15dp"
|
||||
android:paddingBottom="5dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/dialog_et_remark"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入备注信息"
|
||||
android:inputType="textMultiLine"
|
||||
android:minLines="3"
|
||||
android:gravity="top|start"
|
||||
android:padding="10dp"
|
||||
android:background="@android:drawable/edit_text"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="20dp"
|
||||
android:gravity="end">
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="取消"
|
||||
android:layout_marginEnd="10dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/dialog_btn_save"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="保存"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/bg_frame"
|
||||
android:padding="10dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:id="@+id/itemtaskscheduler_llmain">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="任务:"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_task_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/item_btn_schedule"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="▷"
|
||||
android:textSize="12sp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="排档时间:"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_start_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="排档幅度:"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_time_diff"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="#FF1976D2"
|
||||
android:layout_marginStart="10dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="备注:"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_remark"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -20,4 +20,6 @@
|
||||
<!-- 基础颜色 -->
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#000000</color>
|
||||
<!-- 排档时间超过当前时间的列表项背景色 -->
|
||||
<color name="colorScheduleFutureBackground">#FFC8E6C9</color>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user