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
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.GestureDetector
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.network.ApiResult
|
||||
import com.xiaoqu.watch.network.api.TaskApi
|
||||
import com.xiaoqu.watch.network.safeApiCall
|
||||
import com.xiaoqu.watch.ui.common.BaseFragment
|
||||
import com.xiaoqu.watch.ui.widget.QuTipDialog
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* 任务列表页
|
||||
* 分段控件切换状态(接单池2/待打卡3/待完成4)
|
||||
* RecyclerView 显示任务卡片,点击进入详情
|
||||
* 任务列表页(单任务全屏展示,上下滑切换)
|
||||
*
|
||||
* 流程(和旧版一致):
|
||||
* 1. queryTaskIds 获取 ID+name 列表
|
||||
* 2. lookTaskDetail 获取当前任务完整详情
|
||||
* 3. 上滑/下滑切换 taskIndex → 重新获取详情
|
||||
* 4. 操作成功 → 刷新详情 → 刷新列表
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
|
||||
@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 lateinit var adapter: TaskListAdapter
|
||||
|
||||
/** 分段控件的 3 个 Tab */
|
||||
/** 分段控件 Tab */
|
||||
private lateinit var segTabs: List<TextView>
|
||||
|
||||
/** 提示弹窗 */
|
||||
private lateinit var tipDialog: QuTipDialog
|
||||
|
||||
/** 手势检测(上下滑切换任务) */
|
||||
private lateinit var gestureDetector: GestureDetector
|
||||
|
||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTaskListBinding {
|
||||
return FragmentTaskListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// 从导航参数获取初始状态(首页快捷区传入)
|
||||
// 从导航参数获取初始状态
|
||||
currentStatus = arguments?.getInt("tableStatus", 2) ?: 2
|
||||
|
||||
// 初始化弹窗
|
||||
val dialogContainer = requireActivity().findViewById<FrameLayout>(R.id.dialog_container)
|
||||
tipDialog = QuTipDialog(dialogContainer)
|
||||
|
||||
// 返回按钮
|
||||
binding.btnBack.setOnClickListener {
|
||||
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)
|
||||
binding.segPool.setOnClickListener { switchStatus(2) }
|
||||
binding.segPunch.setOnClickListener { switchStatus(3) }
|
||||
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)
|
||||
}
|
||||
|
||||
/** 从详情页返回时自动刷新 */
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
fetchTasks()
|
||||
}
|
||||
// ===== 状态切换 =====
|
||||
|
||||
/** 切换状态 Tab */
|
||||
private fun switchStatus(status: Int) {
|
||||
currentStatus = status
|
||||
taskIndex = 0
|
||||
updateSegmentUI()
|
||||
updateTitle()
|
||||
fetchTasks()
|
||||
fetchTaskIds()
|
||||
}
|
||||
|
||||
/** 更新分段控件高亮 */
|
||||
@@ -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) {
|
||||
2 -> "接单池"
|
||||
3 -> "待打卡"
|
||||
@@ -114,29 +410,17 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 从 API 获取任务列表 */
|
||||
private fun fetchTasks() {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
binding.swipeRefresh.isRefreshing = true
|
||||
val params = hashMapOf<String, Any>("status" to currentStatus)
|
||||
val result = safeApiCall { taskApi.getTaskIds(params) }
|
||||
binding.swipeRefresh.isRefreshing = false
|
||||
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
val tasks = result.data ?: emptyList()
|
||||
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())
|
||||
}
|
||||
}
|
||||
/** 显示空状态 */
|
||||
private fun showEmpty() {
|
||||
binding.taskContent.visibility = View.GONE
|
||||
binding.tvEmpty.visibility = View.VISIBLE
|
||||
binding.loadingWrap.visibility = View.GONE
|
||||
binding.btnAction.visibility = View.GONE
|
||||
binding.tvTitle.text = when (currentStatus) {
|
||||
2 -> "接单池"
|
||||
3 -> "待打卡"
|
||||
4 -> "待完成"
|
||||
else -> "任务列表"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,37 @@
|
||||
<?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_height="match_parent"
|
||||
android:background="@color/background"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/background">
|
||||
|
||||
<!-- 可滑动内容区(底部留出按钮空间) -->
|
||||
<ScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none"
|
||||
android:paddingStart="21dp"
|
||||
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
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<!-- 返回按钮 -->
|
||||
<TextView
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="32dp"
|
||||
@@ -26,14 +41,12 @@
|
||||
android:textColor="@color/primary"
|
||||
android:textSize="27sp" />
|
||||
|
||||
<!-- 标题 -->
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="接单池"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
@@ -84,20 +97,144 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 任务列表(下拉刷新 + RecyclerView) -->
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefresh"
|
||||
<!-- 任务详情区域(lookTaskDetail 数据) -->
|
||||
<LinearLayout
|
||||
android:id="@+id/taskContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
android:layout_height="wrap_content"
|
||||
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_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="27dp" />
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
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" />
|
||||
|
||||
<!-- 地点 -->
|
||||
<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