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 dotPool: View
|
||||||
private lateinit var dotPunch: View
|
private lateinit var dotPunch: View
|
||||||
private lateinit var dotComplete: View
|
private lateinit var dotComplete: View
|
||||||
|
// 新任务提示条
|
||||||
|
private lateinit var tvNewTaskHint: TextView
|
||||||
|
|
||||||
// ===== 设置页 View 引用 =====
|
// ===== 设置页 View 引用 =====
|
||||||
private lateinit var tvAvatarLetter: TextView
|
private lateinit var tvAvatarLetter: TextView
|
||||||
@@ -128,12 +130,14 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
// 从其他页面返回时,有未读通知 → 直接显示红点(不靠 diffStats)
|
// 从其他页面返回时,恢复新任务提示
|
||||||
// 原因:onViewCreated 的 fetchStatistics 已更新 lastStats,diffStats 对比不出差异
|
|
||||||
if (notificationManager.pendingCount > 0) {
|
if (notificationManager.pendingCount > 0) {
|
||||||
|
// 红点(不靠 diffStats,直接显示)
|
||||||
dotPool.visibility = View.VISIBLE
|
dotPool.visibility = View.VISIBLE
|
||||||
dotPunch.visibility = View.VISIBLE
|
dotPunch.visibility = View.VISIBLE
|
||||||
dotComplete.visibility = View.VISIBLE
|
dotComplete.visibility = View.VISIBLE
|
||||||
|
// 提示条
|
||||||
|
updateNewTaskHint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +284,12 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||||||
dotPunch = page.findViewById(R.id.dotPunch)
|
dotPunch = page.findViewById(R.id.dotPunch)
|
||||||
dotComplete = page.findViewById(R.id.dotComplete)
|
dotComplete = page.findViewById(R.id.dotComplete)
|
||||||
|
|
||||||
|
// 新任务提示条
|
||||||
|
tvNewTaskHint = page.findViewById(R.id.tvNewTaskHint)
|
||||||
|
tvNewTaskHint.setOnClickListener {
|
||||||
|
navigateToNewTasks()
|
||||||
|
}
|
||||||
|
|
||||||
// 快捷区卡片点击 → 跳转任务列表 + 清除红点
|
// 快捷区卡片点击 → 跳转任务列表 + 清除红点
|
||||||
page.findViewById<View>(R.id.cardPool)?.setOnClickListener {
|
page.findViewById<View>(R.id.cardPool)?.setOnClickListener {
|
||||||
dotPool.visibility = View.GONE
|
dotPool.visibility = View.GONE
|
||||||
@@ -429,10 +439,11 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||||||
is AppEvent.BluetoothStateChanged -> {
|
is AppEvent.BluetoothStateChanged -> {
|
||||||
statusBar.updateBluetooth(event.isOn)
|
statusBar.updateBluetooth(event.isOn)
|
||||||
}
|
}
|
||||||
// 新任务到达 → 刷新统计 + 红点
|
// 新任务到达 → 刷新统计 + 红点 + 提示条
|
||||||
is AppEvent.NewTaskArrived -> {
|
is AppEvent.NewTaskArrived -> {
|
||||||
Timber.d("首页: 新任务到达 (${event.count} 条)")
|
Timber.d("首页: 新任务到达 (${event.count} 条)")
|
||||||
fetchStatistics(checkDots = true)
|
fetchStatistics(checkDots = true)
|
||||||
|
updateNewTaskHint()
|
||||||
setupBannerClick(event.taskIds)
|
setupBannerClick(event.taskIds)
|
||||||
}
|
}
|
||||||
// MQTT 消息
|
// MQTT 消息
|
||||||
@@ -524,37 +535,57 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||||||
findNavController().navigate(R.id.action_home_to_taskList, bundle)
|
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 navigateToNewTasks() {
|
||||||
|
val currentDest = findNavController().currentDestination?.id
|
||||||
|
if (currentDest != R.id.homeFragment) return
|
||||||
|
|
||||||
|
val allIds = notificationManager.pendingTaskIds
|
||||||
|
if (allIds.isEmpty()) return
|
||||||
|
|
||||||
|
if (allIds.size == 1) {
|
||||||
|
val taskId = allIds.first().toLongOrNull() ?: 0L
|
||||||
|
val bundle = bundleOf("taskId" to taskId)
|
||||||
|
findNavController().navigate(R.id.action_home_to_taskDetail, bundle)
|
||||||
|
} else {
|
||||||
|
val bundle = bundleOf(
|
||||||
|
"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>) {
|
private fun setupBannerClick(taskIds: List<String>) {
|
||||||
val mainActivity = activity as? com.xiaoqu.watch.app.MainActivity ?: return
|
val mainActivity = activity as? com.xiaoqu.watch.app.MainActivity ?: return
|
||||||
mainActivity.notificationBanner.onClick = {
|
mainActivity.notificationBanner.onClick = {
|
||||||
val currentDest = findNavController().currentDestination?.id
|
navigateToNewTasks()
|
||||||
if (currentDest == R.id.homeFragment) {
|
|
||||||
// 取所有累积的任务 ID(不是事件参数的,防覆盖丢失)
|
|
||||||
val allIds = notificationManager.pendingTaskIds
|
|
||||||
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 只显示新任务)
|
|
||||||
val bundle = bundleOf(
|
|
||||||
"tableStatus" to 2,
|
|
||||||
"taskIds" to allIds.mapNotNull { it.toLongOrNull() }.toLongArray()
|
|
||||||
)
|
|
||||||
findNavController().navigate(R.id.action_home_to_taskList, bundle)
|
|
||||||
}
|
|
||||||
// 清除所有红点和未读
|
|
||||||
dotPool.visibility = View.GONE
|
|
||||||
dotPunch.visibility = View.GONE
|
|
||||||
dotComplete.visibility = View.GONE
|
|
||||||
notificationManager.consumeAll()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,22 +120,29 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
|||||||
/** 第一步:获取任务 ID 列表 */
|
/** 第一步:获取任务 ID 列表 */
|
||||||
private fun fetchTaskIds() {
|
private fun fetchTaskIds() {
|
||||||
showLoading()
|
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 {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
val params = hashMapOf<String, Any>("status" to currentStatus)
|
val params = hashMapOf<String, Any>("status" to currentStatus)
|
||||||
val result = safeApiCall { taskApi.getTaskIds(params) }
|
val result = safeApiCall { taskApi.getTaskIds(params) }
|
||||||
|
|
||||||
when (result) {
|
when (result) {
|
||||||
is ApiResult.Success -> {
|
is ApiResult.Success -> {
|
||||||
var list = result.data ?: emptyList()
|
taskList = result.data ?: emptyList()
|
||||||
// 如果有 taskIds 过滤(通知跳转),只保留指定任务
|
Timber.d("任务列表: status=$currentStatus, count=${taskList.size}")
|
||||||
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}")
|
|
||||||
if (taskList.isNotEmpty()) {
|
if (taskList.isNotEmpty()) {
|
||||||
// 确保 taskIndex 在范围内
|
// 确保 taskIndex 在范围内
|
||||||
if (taskIndex >= taskList.size) taskIndex = taskList.size - 1
|
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>
|
</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 -->
|
<!-- 快捷区 gap:6px→8dp -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
Reference in New Issue
Block a user