feat: 新任务提示条 + 按taskIds直接加载
1. 首页新增"有N条新任务 点击查看"提示条 - pendingCount>0 时显示,点击/查看后消失 - 和红点共存:提示条=统一入口,红点=分类提示 2. TaskListFragment 通知模式 - 有 filterTaskIds 时跳过 queryTaskIds - 直接按 taskId 构建列表,调 lookTaskDetail 加载详情 - 不受 status 筛选限制,跨状态任务都能显示 3. 横幅/提示条共用 navigateToNewTasks() - 1个任务→跳详情,多个→跳列表 - 跳转后清除红点+提示条+pendingTaskIds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,6 +69,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
private lateinit var dotPool: View
|
||||
private lateinit var dotPunch: View
|
||||
private lateinit var dotComplete: View
|
||||
// 新任务提示条
|
||||
private lateinit var tvNewTaskHint: TextView
|
||||
|
||||
// ===== 设置页 View 引用 =====
|
||||
private lateinit var tvAvatarLetter: TextView
|
||||
@@ -128,12 +130,14 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// 从其他页面返回时,有未读通知 → 直接显示红点(不靠 diffStats)
|
||||
// 原因:onViewCreated 的 fetchStatistics 已更新 lastStats,diffStats 对比不出差异
|
||||
// 从其他页面返回时,恢复新任务提示
|
||||
if (notificationManager.pendingCount > 0) {
|
||||
// 红点(不靠 diffStats,直接显示)
|
||||
dotPool.visibility = View.VISIBLE
|
||||
dotPunch.visibility = View.VISIBLE
|
||||
dotComplete.visibility = View.VISIBLE
|
||||
// 提示条
|
||||
updateNewTaskHint()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,6 +284,12 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
dotPunch = page.findViewById(R.id.dotPunch)
|
||||
dotComplete = page.findViewById(R.id.dotComplete)
|
||||
|
||||
// 新任务提示条
|
||||
tvNewTaskHint = page.findViewById(R.id.tvNewTaskHint)
|
||||
tvNewTaskHint.setOnClickListener {
|
||||
navigateToNewTasks()
|
||||
}
|
||||
|
||||
// 快捷区卡片点击 → 跳转任务列表 + 清除红点
|
||||
page.findViewById<View>(R.id.cardPool)?.setOnClickListener {
|
||||
dotPool.visibility = View.GONE
|
||||
@@ -429,10 +439,11 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
is AppEvent.BluetoothStateChanged -> {
|
||||
statusBar.updateBluetooth(event.isOn)
|
||||
}
|
||||
// 新任务到达 → 刷新统计 + 红点
|
||||
// 新任务到达 → 刷新统计 + 红点 + 提示条
|
||||
is AppEvent.NewTaskArrived -> {
|
||||
Timber.d("首页: 新任务到达 (${event.count} 条)")
|
||||
fetchStatistics(checkDots = true)
|
||||
updateNewTaskHint()
|
||||
setupBannerClick(event.taskIds)
|
||||
}
|
||||
// MQTT 消息
|
||||
@@ -524,37 +535,57 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
findNavController().navigate(R.id.action_home_to_taskList, bundle)
|
||||
}
|
||||
|
||||
/** 更新新任务提示条 */
|
||||
private fun updateNewTaskHint() {
|
||||
val count = notificationManager.pendingCount
|
||||
if (count > 0) {
|
||||
tvNewTaskHint.text = "有${count}条新任务 点击查看"
|
||||
tvNewTaskHint.visibility = View.VISIBLE
|
||||
} else {
|
||||
tvNewTaskHint.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置通知横幅点击回调
|
||||
* 点击时从 notificationManager.pendingTaskIds 取所有累积的任务 ID
|
||||
* 1 个任务 → 跳任务详情;多个 → 跳任务列表(传 taskIds 只显示新任务)
|
||||
* 跳转查看所有新任务(横幅/提示条共用)
|
||||
* 1 个任务 → 跳详情;多个 → 跳列表按 taskIds 加载
|
||||
*/
|
||||
private fun setupBannerClick(taskIds: List<String>) {
|
||||
val mainActivity = activity as? com.xiaoqu.watch.app.MainActivity ?: return
|
||||
mainActivity.notificationBanner.onClick = {
|
||||
private fun navigateToNewTasks() {
|
||||
val currentDest = findNavController().currentDestination?.id
|
||||
if (currentDest == R.id.homeFragment) {
|
||||
// 取所有累积的任务 ID(不是事件参数的,防覆盖丢失)
|
||||
if (currentDest != R.id.homeFragment) return
|
||||
|
||||
val allIds = notificationManager.pendingTaskIds
|
||||
if (allIds.isEmpty()) return
|
||||
|
||||
if (allIds.size == 1) {
|
||||
// 1 个任务 → 直接跳详情
|
||||
val taskId = allIds.first().toLongOrNull() ?: 0L
|
||||
val bundle = bundleOf("taskId" to taskId)
|
||||
findNavController().navigate(R.id.action_home_to_taskDetail, bundle)
|
||||
} else if (allIds.isNotEmpty()) {
|
||||
// 多个任务 → 跳任务列表(传 taskIds 只显示新任务)
|
||||
} else {
|
||||
val bundle = bundleOf(
|
||||
"tableStatus" to 2,
|
||||
"taskIds" to allIds.mapNotNull { it.toLongOrNull() }.toLongArray()
|
||||
)
|
||||
findNavController().navigate(R.id.action_home_to_taskList, bundle)
|
||||
}
|
||||
// 清除所有红点和未读
|
||||
|
||||
// 清除所有提示
|
||||
clearNewTaskIndicators()
|
||||
}
|
||||
|
||||
/** 清除所有新任务提示(红点+提示条+未读) */
|
||||
private fun clearNewTaskIndicators() {
|
||||
dotPool.visibility = View.GONE
|
||||
dotPunch.visibility = View.GONE
|
||||
dotComplete.visibility = View.GONE
|
||||
tvNewTaskHint.visibility = View.GONE
|
||||
notificationManager.consumeAll()
|
||||
}
|
||||
|
||||
/** 设置通知横幅点击回调 */
|
||||
private fun setupBannerClick(taskIds: List<String>) {
|
||||
val mainActivity = activity as? com.xiaoqu.watch.app.MainActivity ?: return
|
||||
mainActivity.notificationBanner.onClick = {
|
||||
navigateToNewTasks()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,22 +120,29 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
/** 第一步:获取任务 ID 列表 */
|
||||
private fun fetchTaskIds() {
|
||||
showLoading()
|
||||
|
||||
// 通知跳转:有 taskIds 时不走 queryTaskIds,直接按 ID 构建列表
|
||||
val ids = filterTaskIds
|
||||
if (ids != null && ids.isNotEmpty()) {
|
||||
taskList = ids.map { TaskItem(id = it) }
|
||||
Timber.d("任务列表: 通知模式, ${ids.size} 个任务")
|
||||
if (taskList.isNotEmpty()) {
|
||||
fetchCurrentDetail()
|
||||
} else {
|
||||
showEmpty()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 正常流程:按 status 筛选
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val params = hashMapOf<String, Any>("status" to currentStatus)
|
||||
val result = safeApiCall { taskApi.getTaskIds(params) }
|
||||
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
var list = result.data ?: emptyList()
|
||||
// 如果有 taskIds 过滤(通知跳转),只保留指定任务
|
||||
val ids = filterTaskIds
|
||||
if (ids != null && ids.isNotEmpty()) {
|
||||
list = list.filter { item ->
|
||||
ids.any { it.toString() == item.id.toString() }
|
||||
}
|
||||
}
|
||||
taskList = list
|
||||
Timber.d("任务列表: status=$currentStatus, count=${taskList.size}, filter=${ids?.size ?: 0}")
|
||||
taskList = result.data ?: emptyList()
|
||||
Timber.d("任务列表: status=$currentStatus, count=${taskList.size}")
|
||||
if (taskList.isNotEmpty()) {
|
||||
// 确保 taskIndex 在范围内
|
||||
if (taskIndex >= taskList.size) taskIndex = taskList.size - 1
|
||||
|
||||
7
app/src/main/res/drawable/bg_new_task_hint.xml
Normal file
7
app/src/main/res/drawable/bg_new_task_hint.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 新任务提示条背景(蓝色半透明圆角) -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#1A3B9EFF" />
|
||||
<corners android:radius="12dp" />
|
||||
</shape>
|
||||
@@ -42,6 +42,22 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 新任务提示条(pendingCount>0 时显示,点击查看所有新任务) -->
|
||||
<TextView
|
||||
android:id="@+id/tvNewTaskHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/bg_new_task_hint"
|
||||
android:gravity="center"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:text="有1条新任务 点击查看"
|
||||
android:textColor="#FF3B9EFF"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- 快捷区 gap:6px→8dp -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user