feat: 任务列表改为单任务全屏展示+上下滑切换(方案B,和旧版一致)
核心改动: - queryTaskIds 获取ID列表 → lookTaskDetail 获取当前任务详情 - 上滑下一个、下滑上一个任务 - 顶部显示"第X/Y个任务" - 派单时间+任务名(带类型前缀)+地点+派单号+积分+协作人+描述 - 底部固定操作按钮(抢单/打卡/完成) - 操作成功后刷新列表+详情 - 空状态+Loading状态 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,93 +1,131 @@
|
|||||||
package com.xiaoqu.watch.ui.task
|
package com.xiaoqu.watch.ui.task
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.GestureDetector
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.os.bundleOf
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import com.xiaoqu.watch.R
|
import com.xiaoqu.watch.R
|
||||||
|
import com.xiaoqu.watch.data.task.TaskDetail
|
||||||
|
import com.xiaoqu.watch.data.task.TaskItem
|
||||||
import com.xiaoqu.watch.databinding.FragmentTaskListBinding
|
import com.xiaoqu.watch.databinding.FragmentTaskListBinding
|
||||||
import com.xiaoqu.watch.network.ApiResult
|
import com.xiaoqu.watch.network.ApiResult
|
||||||
import com.xiaoqu.watch.network.api.TaskApi
|
import com.xiaoqu.watch.network.api.TaskApi
|
||||||
import com.xiaoqu.watch.network.safeApiCall
|
import com.xiaoqu.watch.network.safeApiCall
|
||||||
import com.xiaoqu.watch.ui.common.BaseFragment
|
import com.xiaoqu.watch.ui.common.BaseFragment
|
||||||
|
import com.xiaoqu.watch.ui.widget.QuTipDialog
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务列表页
|
* 任务列表页(单任务全屏展示,上下滑切换)
|
||||||
* 分段控件切换状态(接单池2/待打卡3/待完成4)
|
*
|
||||||
* RecyclerView 显示任务卡片,点击进入详情
|
* 流程(和旧版一致):
|
||||||
|
* 1. queryTaskIds 获取 ID+name 列表
|
||||||
|
* 2. lookTaskDetail 获取当前任务完整详情
|
||||||
|
* 3. 上滑/下滑切换 taskIndex → 重新获取详情
|
||||||
|
* 4. 操作成功 → 刷新详情 → 刷新列表
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||||
|
|
||||||
@Inject lateinit var taskApi: TaskApi
|
@Inject lateinit var taskApi: TaskApi
|
||||||
|
|
||||||
/** 当前选中的状态 */
|
/** 任务 ID 列表(queryTaskIds 返回) */
|
||||||
|
private var taskList: List<TaskItem> = emptyList()
|
||||||
|
|
||||||
|
/** 当前任务索引 */
|
||||||
|
private var taskIndex = 0
|
||||||
|
|
||||||
|
/** 当前任务详情 */
|
||||||
|
private var currentDetail: TaskDetail? = null
|
||||||
|
|
||||||
|
/** 当前状态筛选 */
|
||||||
private var currentStatus = 2
|
private var currentStatus = 2
|
||||||
|
|
||||||
/** 列表适配器 */
|
/** 分段控件 Tab */
|
||||||
private lateinit var adapter: TaskListAdapter
|
|
||||||
|
|
||||||
/** 分段控件的 3 个 Tab */
|
|
||||||
private lateinit var segTabs: List<TextView>
|
private lateinit var segTabs: List<TextView>
|
||||||
|
|
||||||
|
/** 提示弹窗 */
|
||||||
|
private lateinit var tipDialog: QuTipDialog
|
||||||
|
|
||||||
|
/** 手势检测(上下滑切换任务) */
|
||||||
|
private lateinit var gestureDetector: GestureDetector
|
||||||
|
|
||||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTaskListBinding {
|
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTaskListBinding {
|
||||||
return FragmentTaskListBinding.inflate(inflater, container, false)
|
return FragmentTaskListBinding.inflate(inflater, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
// 从导航参数获取初始状态(首页快捷区传入)
|
// 从导航参数获取初始状态
|
||||||
currentStatus = arguments?.getInt("tableStatus", 2) ?: 2
|
currentStatus = arguments?.getInt("tableStatus", 2) ?: 2
|
||||||
|
|
||||||
|
// 初始化弹窗
|
||||||
|
val dialogContainer = requireActivity().findViewById<FrameLayout>(R.id.dialog_container)
|
||||||
|
tipDialog = QuTipDialog(dialogContainer)
|
||||||
|
|
||||||
// 返回按钮
|
// 返回按钮
|
||||||
binding.btnBack.setOnClickListener {
|
binding.btnBack.setOnClickListener {
|
||||||
findNavController().popBackStack()
|
findNavController().popBackStack()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化 RecyclerView
|
// 分段控件
|
||||||
adapter = TaskListAdapter { task ->
|
|
||||||
// 点击任务卡片 → 跳转详情
|
|
||||||
val bundle = bundleOf("taskId" to task.id)
|
|
||||||
findNavController().navigate(R.id.action_taskList_to_detail, bundle)
|
|
||||||
}
|
|
||||||
binding.rvTasks.layoutManager = LinearLayoutManager(requireContext())
|
|
||||||
binding.rvTasks.adapter = adapter
|
|
||||||
|
|
||||||
// 初始化分段控件
|
|
||||||
segTabs = listOf(binding.segPool, binding.segPunch, binding.segComplete)
|
segTabs = listOf(binding.segPool, binding.segPunch, binding.segComplete)
|
||||||
binding.segPool.setOnClickListener { switchStatus(2) }
|
binding.segPool.setOnClickListener { switchStatus(2) }
|
||||||
binding.segPunch.setOnClickListener { switchStatus(3) }
|
binding.segPunch.setOnClickListener { switchStatus(3) }
|
||||||
binding.segComplete.setOnClickListener { switchStatus(4) }
|
binding.segComplete.setOnClickListener { switchStatus(4) }
|
||||||
|
|
||||||
// 下拉刷新
|
// 上下滑手势(切换任务)
|
||||||
binding.swipeRefresh.setOnRefreshListener { fetchTasks() }
|
gestureDetector = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
|
||||||
|
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||||
|
if (e1 == null) return false
|
||||||
|
val dy = e2.y - e1.y
|
||||||
|
val dx = e2.x - e1.x
|
||||||
|
// 垂直滑动且幅度 > 水平
|
||||||
|
if (abs(dy) > abs(dx) && abs(dy) > 50) {
|
||||||
|
if (dy < 0) {
|
||||||
|
// 上滑 → 下一个任务
|
||||||
|
nextTask()
|
||||||
|
} else {
|
||||||
|
// 下滑 → 上一个任务
|
||||||
|
prevTask()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 设置初始状态并加载数据
|
// 给 ScrollView 设置触摸监听
|
||||||
|
binding.scrollView.setOnTouchListener { _, event ->
|
||||||
|
gestureDetector.onTouchEvent(event)
|
||||||
|
false // 不拦截,让 ScrollView 继续处理滚动
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
switchStatus(currentStatus)
|
switchStatus(currentStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 从详情页返回时自动刷新 */
|
// ===== 状态切换 =====
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
fetchTasks()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 切换状态 Tab */
|
/** 切换状态 Tab */
|
||||||
private fun switchStatus(status: Int) {
|
private fun switchStatus(status: Int) {
|
||||||
currentStatus = status
|
currentStatus = status
|
||||||
|
taskIndex = 0
|
||||||
updateSegmentUI()
|
updateSegmentUI()
|
||||||
updateTitle()
|
fetchTaskIds()
|
||||||
fetchTasks()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 更新分段控件高亮 */
|
/** 更新分段控件高亮 */
|
||||||
@@ -104,8 +142,266 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 更新页面标题 */
|
// ===== 数据获取 =====
|
||||||
private fun updateTitle() {
|
|
||||||
|
/** 第一步:获取任务 ID 列表 */
|
||||||
|
private fun fetchTaskIds() {
|
||||||
|
showLoading()
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
val params = hashMapOf<String, Any>("status" to currentStatus)
|
||||||
|
val result = safeApiCall { taskApi.getTaskIds(params) }
|
||||||
|
|
||||||
|
when (result) {
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
taskList = result.data ?: emptyList()
|
||||||
|
Timber.d("任务列表: status=$currentStatus, count=${taskList.size}")
|
||||||
|
if (taskList.isNotEmpty()) {
|
||||||
|
// 确保 taskIndex 在范围内
|
||||||
|
if (taskIndex >= taskList.size) taskIndex = taskList.size - 1
|
||||||
|
fetchCurrentDetail()
|
||||||
|
} else {
|
||||||
|
showEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
Timber.w("任务列表: API 错误 ${result.code} ${result.message}")
|
||||||
|
taskList = emptyList()
|
||||||
|
showEmpty()
|
||||||
|
}
|
||||||
|
is ApiResult.NetworkError -> {
|
||||||
|
Timber.w("任务列表: 网络异常")
|
||||||
|
taskList = emptyList()
|
||||||
|
showEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 第二步:获取当前任务详情 */
|
||||||
|
private fun fetchCurrentDetail() {
|
||||||
|
if (taskList.isEmpty()) return
|
||||||
|
val taskId = taskList[taskIndex].id
|
||||||
|
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
val params = hashMapOf<String, Any>("id" to taskId)
|
||||||
|
val result = safeApiCall { taskApi.getTaskDetail(params) }
|
||||||
|
|
||||||
|
when (result) {
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
result.data?.let { detail ->
|
||||||
|
currentDetail = detail
|
||||||
|
displayDetail(detail)
|
||||||
|
setupActionButton(detail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
Timber.w("任务详情: API 错误 ${result.code}")
|
||||||
|
}
|
||||||
|
is ApiResult.NetworkError -> {
|
||||||
|
Timber.w("任务详情: 网络异常")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 上下滑切换 =====
|
||||||
|
|
||||||
|
/** 下一个任务(上滑) */
|
||||||
|
private fun nextTask() {
|
||||||
|
if (taskIndex < taskList.size - 1) {
|
||||||
|
taskIndex++
|
||||||
|
fetchCurrentDetail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上一个任务(下滑) */
|
||||||
|
private fun prevTask() {
|
||||||
|
if (taskIndex > 0) {
|
||||||
|
taskIndex--
|
||||||
|
fetchCurrentDetail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== UI 显示 =====
|
||||||
|
|
||||||
|
/** 显示任务详情 */
|
||||||
|
private fun displayDetail(detail: TaskDetail) {
|
||||||
|
binding.taskContent.visibility = View.VISIBLE
|
||||||
|
binding.tvEmpty.visibility = View.GONE
|
||||||
|
binding.loadingWrap.visibility = View.GONE
|
||||||
|
|
||||||
|
// 标题:第X/Y个任务
|
||||||
|
binding.tvTitle.text = "第${taskIndex + 1}/${taskList.size}个任务"
|
||||||
|
|
||||||
|
// 派单时间
|
||||||
|
if (detail.beginTime.isNotEmpty()) {
|
||||||
|
val timePart = detail.beginTime.split(" ").lastOrNull() ?: detail.beginTime
|
||||||
|
binding.tvSendTime.text = "${timePart}派单"
|
||||||
|
binding.tvSendTime.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvSendTime.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// 任务名(带类型前缀)
|
||||||
|
val prefix = when (detail.taskType) {
|
||||||
|
2 -> "指派:"
|
||||||
|
3, 4 -> "上报:"
|
||||||
|
5 -> "巡检:"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
binding.tvTaskName.text = "$prefix${detail.taskName.ifEmpty { detail.no }}"
|
||||||
|
|
||||||
|
// 地点
|
||||||
|
if (detail.positionName.isNotEmpty()) {
|
||||||
|
binding.tvPosition.text = detail.positionName
|
||||||
|
binding.tvPosition.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvPosition.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// 派单号
|
||||||
|
binding.tvNo.text = detail.no
|
||||||
|
|
||||||
|
// 积分
|
||||||
|
binding.tvPoints.text = if (detail.point > 0) "+${detail.point}" else "0"
|
||||||
|
|
||||||
|
// 协作人
|
||||||
|
if (detail.executorName.isNotEmpty()) {
|
||||||
|
binding.tvWorkers.text = detail.executorName
|
||||||
|
binding.rowWorkers.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.rowWorkers.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// 描述
|
||||||
|
if (detail.description.isNotEmpty()) {
|
||||||
|
binding.tvDescription.text = detail.description
|
||||||
|
binding.tvDescription.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvDescription.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提示条(待打卡+有场景)
|
||||||
|
if (detail.status == 3 && detail.hasPosition) {
|
||||||
|
binding.tvHint.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvHint.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据状态设置底部操作按钮 */
|
||||||
|
private fun setupActionButton(detail: TaskDetail) {
|
||||||
|
val btn = binding.btnAction
|
||||||
|
btn.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
when (detail.status) {
|
||||||
|
// 待抢单 → 蓝色「抢 单」
|
||||||
|
2 -> {
|
||||||
|
btn.text = "抢 单"
|
||||||
|
btn.setBackgroundResource(R.drawable.bg_foot_btn_blue)
|
||||||
|
btn.setTextColor(requireContext().getColor(R.color.text_primary))
|
||||||
|
btn.setOnClickListener { doAction("grab", detail.id) }
|
||||||
|
}
|
||||||
|
// 待打卡
|
||||||
|
3 -> {
|
||||||
|
if (detail.hasPosition) {
|
||||||
|
// 有场景 → 橙色「开启打卡」
|
||||||
|
btn.text = "开启打卡"
|
||||||
|
btn.setBackgroundResource(R.drawable.bg_foot_btn_orange)
|
||||||
|
btn.setTextColor(requireContext().getColor(R.color.background))
|
||||||
|
btn.setOnClickListener {
|
||||||
|
// TODO: NFC 打卡流程
|
||||||
|
Timber.d("NFC 打卡(后续实现)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 无场景 → 绿色「确认打卡」
|
||||||
|
btn.text = "确认打卡"
|
||||||
|
btn.setBackgroundResource(R.drawable.bg_foot_btn_green)
|
||||||
|
btn.setTextColor(requireContext().getColor(R.color.text_primary))
|
||||||
|
btn.setOnClickListener { doAction("assign", detail.id) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进行中 → 绿色「确认完成」
|
||||||
|
4 -> {
|
||||||
|
btn.text = "确认完成"
|
||||||
|
btn.setBackgroundResource(R.drawable.bg_foot_btn_green)
|
||||||
|
btn.setTextColor(requireContext().getColor(R.color.text_primary))
|
||||||
|
btn.setOnClickListener { doAction("complete", detail.id) }
|
||||||
|
}
|
||||||
|
// 其他 → 灰色「返回」
|
||||||
|
else -> {
|
||||||
|
btn.text = "返 回"
|
||||||
|
btn.setBackgroundResource(R.drawable.bg_foot_btn_blue)
|
||||||
|
btn.setTextColor(requireContext().getColor(R.color.text_primary))
|
||||||
|
btn.setOnClickListener { findNavController().popBackStack() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 操作 =====
|
||||||
|
|
||||||
|
/** 执行任务操作(抢单/打卡/完成) */
|
||||||
|
private fun doAction(action: String, taskId: Long) {
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
val params = hashMapOf<String, Any>("id" to taskId)
|
||||||
|
val result = when (action) {
|
||||||
|
"grab" -> safeApiCall { taskApi.grabTask(params) }
|
||||||
|
"assign" -> safeApiCall { taskApi.assignToBeginTask(params) }
|
||||||
|
"complete" -> safeApiCall { taskApi.completeTask(params) }
|
||||||
|
else -> return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
val successMsg = when (action) {
|
||||||
|
"grab" -> "抢单成功"
|
||||||
|
"assign" -> "打卡成功"
|
||||||
|
"complete" -> "任务已完成"
|
||||||
|
else -> "操作成功"
|
||||||
|
}
|
||||||
|
val failMsg = when (action) {
|
||||||
|
"grab" -> "抢单失败"
|
||||||
|
"assign" -> "打卡失败"
|
||||||
|
"complete" -> "完成失败"
|
||||||
|
else -> "操作失败"
|
||||||
|
}
|
||||||
|
|
||||||
|
when (result) {
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
Timber.d("任务操作: $successMsg")
|
||||||
|
tipDialog.show(
|
||||||
|
status = QuTipDialog.Status.SUCCESS,
|
||||||
|
title = successMsg,
|
||||||
|
back = true, step = 0, countdown = 2
|
||||||
|
)
|
||||||
|
// 操作成功后刷新:重新获取列表和详情
|
||||||
|
fetchTaskIds()
|
||||||
|
}
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
tipDialog.show(
|
||||||
|
status = QuTipDialog.Status.ERROR,
|
||||||
|
title = failMsg,
|
||||||
|
desc = result.message,
|
||||||
|
back = true, step = 0, countdown = 3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is ApiResult.NetworkError -> {
|
||||||
|
tipDialog.show(
|
||||||
|
status = QuTipDialog.Status.ERROR,
|
||||||
|
title = "网络异常",
|
||||||
|
back = true, step = 0, countdown = 3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 状态显示 =====
|
||||||
|
|
||||||
|
/** 显示 Loading */
|
||||||
|
private fun showLoading() {
|
||||||
|
binding.taskContent.visibility = View.GONE
|
||||||
|
binding.tvEmpty.visibility = View.GONE
|
||||||
|
binding.loadingWrap.visibility = View.VISIBLE
|
||||||
|
binding.btnAction.visibility = View.GONE
|
||||||
binding.tvTitle.text = when (currentStatus) {
|
binding.tvTitle.text = when (currentStatus) {
|
||||||
2 -> "接单池"
|
2 -> "接单池"
|
||||||
3 -> "待打卡"
|
3 -> "待打卡"
|
||||||
@@ -114,29 +410,17 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 从 API 获取任务列表 */
|
/** 显示空状态 */
|
||||||
private fun fetchTasks() {
|
private fun showEmpty() {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
binding.taskContent.visibility = View.GONE
|
||||||
binding.swipeRefresh.isRefreshing = true
|
binding.tvEmpty.visibility = View.VISIBLE
|
||||||
val params = hashMapOf<String, Any>("status" to currentStatus)
|
binding.loadingWrap.visibility = View.GONE
|
||||||
val result = safeApiCall { taskApi.getTaskIds(params) }
|
binding.btnAction.visibility = View.GONE
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.tvTitle.text = when (currentStatus) {
|
||||||
|
2 -> "接单池"
|
||||||
when (result) {
|
3 -> "待打卡"
|
||||||
is ApiResult.Success -> {
|
4 -> "待完成"
|
||||||
val tasks = result.data ?: emptyList()
|
else -> "任务列表"
|
||||||
Timber.d("任务列表: status=$currentStatus, count=${tasks.size}")
|
|
||||||
adapter.submitList(tasks)
|
|
||||||
}
|
|
||||||
is ApiResult.Error -> {
|
|
||||||
Timber.w("任务列表: API 错误 code=${result.code} ${result.message}")
|
|
||||||
adapter.submitList(emptyList())
|
|
||||||
}
|
|
||||||
is ApiResult.NetworkError -> {
|
|
||||||
Timber.w("任务列表: 网络异常")
|
|
||||||
adapter.submitList(emptyList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,37 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- 任务列表页:返回按钮 + 分段控件 + RecyclerView -->
|
<!-- 任务列表页(单任务展示,上下滑切换)
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
顶部:返回 + "第X/Y个任务" + 分段控件
|
||||||
|
中间:当前任务详情(lookTaskDetail)
|
||||||
|
底部:固定操作按钮 -->
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/background"
|
android:background="@color/background">
|
||||||
android:orientation="vertical"
|
|
||||||
|
<!-- 可滑动内容区(底部留出按钮空间) -->
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/scrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="none"
|
||||||
android:paddingStart="21dp"
|
android:paddingStart="21dp"
|
||||||
android:paddingTop="27dp"
|
android:paddingTop="27dp"
|
||||||
android:paddingEnd="21dp">
|
android:paddingEnd="21dp"
|
||||||
|
android:paddingBottom="72dp"
|
||||||
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<!-- 页面头部:返回 + 标题 -->
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<!-- 页面头部:返回 + 标题(第X/Y个任务) -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layout_marginBottom="8dp">
|
android:layout_marginBottom="8dp">
|
||||||
|
|
||||||
<!-- 返回按钮 -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/btnBack"
|
android:id="@+id/btnBack"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
@@ -26,14 +41,12 @@
|
|||||||
android:textColor="@color/primary"
|
android:textColor="@color/primary"
|
||||||
android:textSize="27sp" />
|
android:textSize="27sp" />
|
||||||
|
|
||||||
<!-- 标题 -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvTitle"
|
android:id="@+id/tvTitle"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="接单池"
|
|
||||||
android:textColor="@color/text_primary"
|
android:textColor="@color/text_primary"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
@@ -84,20 +97,144 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 任务列表(下拉刷新 + RecyclerView) -->
|
<!-- 任务详情区域(lookTaskDetail 数据) -->
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<LinearLayout
|
||||||
android:id="@+id/swipeRefresh"
|
android:id="@+id/taskContent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1">
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<!-- 派单时间 -->
|
||||||
android:id="@+id/rvTasks"
|
<TextView
|
||||||
|
android:id="@+id/tvSendTime"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:gravity="center"
|
||||||
android:paddingBottom="27dp" />
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
<!-- 任务名称(大字居中) -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTaskName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="26sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
<!-- 地点 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPosition"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/primary"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- 信息行列表 -->
|
||||||
|
<LinearLayout style="@style/ConfigRow">
|
||||||
|
<TextView style="@style/ConfigLabel" android:text="派单号" />
|
||||||
|
<TextView android:id="@+id/tvNo" style="@style/ConfigValue"
|
||||||
|
android:textColor="@color/text_secondary" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout style="@style/ConfigRow">
|
||||||
|
<TextView style="@style/ConfigLabel" android:text="积分" />
|
||||||
|
<TextView android:id="@+id/tvPoints" style="@style/ConfigValue"
|
||||||
|
android:textColor="@color/warning" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/rowWorkers" style="@style/ConfigRow"
|
||||||
|
android:visibility="gone">
|
||||||
|
<TextView style="@style/ConfigLabel" android:text="协作人" />
|
||||||
|
<TextView android:id="@+id/tvWorkers" style="@style/ConfigValue" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 任务描述 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvDescription"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:lineSpacingMultiplier="1.5"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<!-- 提示条(待打卡+有场景) -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvHint"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="11dp"
|
||||||
|
android:text="请将手表贴近打卡信标"
|
||||||
|
android:textColor="@color/warning"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvEmpty"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="暂无任务"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:paddingTop="80dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<!-- Loading -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/loadingWrap"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="80dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:indeterminateTint="@color/text_secondary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="加载中"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginTop="8dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<!-- 底部固定操作按钮 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btnAction"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="19dp"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="21sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:letterSpacing="0.05"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user