feat: 任务管理模块 - 列表+详情+抢单/打卡/完成

新增:
- TaskListFragment 分段控件+RecyclerView+下拉刷新
- TaskDetailFragment 信息展示+底部固定操作按钮(foot-btn)
- TaskListAdapter 任务卡片适配器
- TaskItem/TaskDetail 数据类
- TaskApi 新增5个接口(pageList/detail/grab/assign/complete)
- 分段控件/底部按钮/状态标签 drawable

修改:
- nav_main.xml 添加参数和action
- HomeFragment 快捷区点击→任务列表(传tableStatus)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-04-27 20:19:35 +09:30
parent 3c9d74f16c
commit 1056386af8
19 changed files with 889 additions and 43 deletions

View 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="#FF3B9EFF" />
<corners android:bottomLeftRadius="59dp" android:bottomRightRadius="59dp" />
</shape>

View 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="#FF4ADE80" />
<corners android:bottomLeftRadius="59dp" android:bottomRightRadius="59dp" />
</shape>

View 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="#FFFFB340" />
<corners android:bottomLeftRadius="59dp" android:bottomRightRadius="59dp" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#330A84FF" />
<corners android:radius="16dp" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#3330D158" />
<corners android:radius="16dp" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#33FF9F0A" />
<corners android:radius="16dp" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 分段控件选中项背景:白色 12% 圆角 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1FFFFFFF" />
<corners android:radius="8dp" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 分段控件背景:白色 8% 圆角 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#14FFFFFF" />
<corners android:radius="11dp" />
</shape>

View File

@@ -1,9 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 任务详情页ScrollView 信息 + 底部固定操作按钮 -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background">
<!-- TODO: 任务详情 + 操作按钮 -->
<!-- 可滚动内容区(底部留出按钮空间) -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:paddingStart="21dp"
android:paddingTop="27dp"
android:paddingEnd="21dp"
android:paddingBottom="72dp"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- 页面头部:返回 + 标题 -->
<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"
android:layout_height="32dp"
android:gravity="center"
android:text=""
android:textColor="@color/primary"
android:textSize="27sp" />
<TextView
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"
android:layout_marginEnd="32dp" />
</LinearLayout>
<!-- 任务信息行 -->
<LinearLayout style="@style/ConfigRow">
<TextView style="@style/ConfigLabel" android:text="任务" />
<TextView android:id="@+id/tvTaskName" style="@style/ConfigValue" />
</LinearLayout>
<LinearLayout style="@style/ConfigRow">
<TextView style="@style/ConfigLabel" android:text="编号" />
<TextView android:id="@+id/tvTaskNo" style="@style/ConfigValue"
android:textColor="@color/text_secondary" android:textSize="15sp" />
</LinearLayout>
<LinearLayout style="@style/ConfigRow">
<TextView style="@style/ConfigLabel" android:text="地点" />
<TextView android:id="@+id/tvPosition" style="@style/ConfigValue"
android:textColor="@color/primary" />
</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 style="@style/ConfigRow">
<TextView style="@style/ConfigLabel" android:text="派单" />
<TextView android:id="@+id/tvTime" style="@style/ConfigValue" />
</LinearLayout>
<LinearLayout style="@style/ConfigRow">
<TextView style="@style/ConfigLabel" android:text="状态" />
<TextView android:id="@+id/tvStatus" style="@style/ConfigValue" />
</LinearLayout>
<!-- 提示条(待打卡+有场景时显示) -->
<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:visibility="gone" />
</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" />
</FrameLayout>

View File

@@ -1,9 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<!-- 任务列表页:返回按钮 + 分段控件 + RecyclerView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background">
android:background="@color/background"
android:orientation="vertical"
android:paddingStart="21dp"
android:paddingTop="27dp"
android:paddingEnd="21dp">
<!-- TODO: RecyclerView 任务列表 -->
<!-- 页面头部:返回 + 标题 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginBottom="8dp">
</FrameLayout>
<!-- 返回按钮 -->
<TextView
android:id="@+id/btnBack"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:text=""
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"
android:layout_marginEnd="32dp" />
</LinearLayout>
<!-- 分段控件:接单池 / 待打卡 / 待完成 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_seg_ctrl"
android:padding="3dp"
android:layout_marginBottom="13dp">
<TextView
android:id="@+id/segPool"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="8dp"
android:text="接单池"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/segPunch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="8dp"
android:text="待打卡"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/segComplete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="8dp"
android:text="待完成"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 任务列表(下拉刷新 + RecyclerView -->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTasks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="27dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 任务卡片RecyclerView item
显示:任务名 + 地点 + 时间 + 积分 + 状态标签 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_seg_active"
android:orientation="vertical"
android:padding="16dp"
android:layout_marginBottom="11dp">
<!-- 任务名(大字) -->
<TextView
android:id="@+id/tvTaskName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_primary"
android:textSize="20sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end" />
<!-- 地点 + 时间 -->
<TextView
android:id="@+id/tvTaskSub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_secondary"
android:textSize="16sp"
android:lineSpacingMultiplier="1.7"
android:layout_marginTop="8dp" />
<!-- 积分 + 状态标签 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:layout_marginTop="8dp">
<!-- 积分 -->
<TextView
android:id="@+id/tvPoints"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/warning"
android:textSize="19sp"
android:textStyle="bold" />
<!-- 状态标签 -->
<TextView
android:id="@+id/tvStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="13dp"
android:paddingEnd="13dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>

View File

@@ -4,66 +4,60 @@
android:id="@+id/nav_main"
app:startDestination="@id/splashFragment">
<!-- 启动分发页(检查绑定状态 → Home 或 Bind -->
<!-- 启动分发页 -->
<fragment
android:id="@+id/splashFragment"
android:name="com.xiaoqu.watch.ui.common.SplashFragment"
android:label="启动">
<!-- splash → home已绑定 -->
<action
android:id="@+id/action_splash_to_home"
<action android:id="@+id/action_splash_to_home"
app:destination="@id/homeFragment"
app:popUpTo="@id/splashFragment"
app:popUpToInclusive="true" />
<!-- splash → bind未绑定 -->
<action
android:id="@+id/action_splash_to_bind"
app:popUpTo="@id/splashFragment" app:popUpToInclusive="true" />
<action android:id="@+id/action_splash_to_bind"
app:destination="@id/bindFragment"
app:popUpTo="@id/splashFragment"
app:popUpToInclusive="true" />
app:popUpTo="@id/splashFragment" app:popUpToInclusive="true" />
</fragment>
<!-- 首页(含 ViewPager2 左右滑动:设置页 / 主页) -->
<!-- 首页 -->
<fragment
android:id="@+id/homeFragment"
android:name="com.xiaoqu.watch.ui.home.HomeFragment"
android:label="首页">
<!-- home → bind解绑后 -->
<action
android:id="@+id/action_home_to_bind"
<action android:id="@+id/action_home_to_bind"
app:destination="@id/bindFragment"
app:popUpTo="@id/homeFragment"
app:popUpToInclusive="true" />
app:popUpTo="@id/homeFragment" app:popUpToInclusive="true" />
<!-- 首页 → 任务列表 -->
<action android:id="@+id/action_home_to_taskList"
app:destination="@id/taskListFragment" />
</fragment>
<!-- 设备绑定页(全屏二维码) -->
<!-- 设备绑定页 -->
<fragment
android:id="@+id/bindFragment"
android:name="com.xiaoqu.watch.ui.bind.BindFragment"
android:label="设备绑定">
<!-- bind → home绑定成功后 -->
<action
android:id="@+id/action_bind_to_home"
<action android:id="@+id/action_bind_to_home"
app:destination="@id/homeFragment"
app:popUpTo="@id/bindFragment"
app:popUpToInclusive="true" />
app:popUpTo="@id/bindFragment" app:popUpToInclusive="true" />
</fragment>
<!-- 任务列表 -->
<!-- 任务列表(接收 tableStatus 参数) -->
<fragment
android:id="@+id/taskListFragment"
android:name="com.xiaoqu.watch.ui.task.TaskListFragment"
android:label="任务列表" />
android:label="任务列表">
<argument android:name="tableStatus" android:defaultValue="2" app:argType="integer" />
<!-- 任务列表 → 任务详情 -->
<action android:id="@+id/action_taskList_to_detail"
app:destination="@id/taskDetailFragment" />
</fragment>
<!-- 任务详情 -->
<!-- 任务详情(接收 taskId 参数) -->
<fragment
android:id="@+id/taskDetailFragment"
android:name="com.xiaoqu.watch.ui.task.TaskDetailFragment"
android:label="任务详情" />
android:label="任务详情">
<argument android:name="taskId" android:defaultValue="0" app:argType="long" />
</fragment>
<!-- 打卡页 -->
<fragment