日报202563
团队作业开发
修复保养任务和检测任务接取中工单显示错误
package com.example.sanpaias.activity
import android.app.AlertDialog
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.sanpaias.R
import com.example.sanpaias.entity.Device
import com.example.sanpaias.entity.TestingPlan
import com.example.sanpaias.network.RetrofitClient
import com.google.gson.Gson
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import java.text.SimpleDateFormat
import java.util.*
class TestingPlanListActivity : AppCompatActivity() {
private lateinit var rvTestingPlans: RecyclerView
private lateinit var tvNoData: TextView
private lateinit var btnAddPlan: Button
private lateinit var adapter: TestingPlanAdapter
private val testingPlans = mutableListOf<TestingPlan>()
private val devices = mutableListOf<Device>()
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
companion object {
private const val TAG = "TestingPlanListActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_testing_plan_list)
initViews()
setupRecyclerView()
loadDevices()
loadTestingPlans()
}
private fun initViews() {
rvTestingPlans = findViewById(R.id.rvTestingPlans)
tvNoData = findViewById(R.id.tvNoData)
btnAddPlan = findViewById(R.id.btnAddPlan)
btnAddPlan.setOnClickListener {
showAddTestingPlanDialog()
}
}
private fun setupRecyclerView() {
adapter = TestingPlanAdapter(testingPlans) { plan, action ->
when (action) {
"edit" -> showEditTestingPlanDialog(plan)
"delete" -> showDeleteConfirmDialog(plan)
"toggle_status" -> togglePlanStatus(plan)
"enable" -> enablePlan(plan)
"disable" -> disablePlan(plan)
}
}
rvTestingPlans.layoutManager = LinearLayoutManager(this)
rvTestingPlans.adapter = adapter
}
private fun loadDevices() {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getAllDevices()
if (response.isSuccessful && response.body()?.code == 200) {
devices.clear()
devices.addAll(response.body()?.data ?: emptyList())
}
} catch (e: Exception) {
Log.e(TAG, "加载设备列表失败", e)
}
}
}
private fun loadTestingPlans() {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.getTestingPlanList()
if (response.isSuccessful && response.body()?.code == 200) {
testingPlans.clear()
testingPlans.addAll(response.body()?.data ?: emptyList())
adapter.notifyDataSetChanged()
if (testingPlans.isEmpty()) {
tvNoData.visibility = View.VISIBLE
rvTestingPlans.visibility = View.GONE
} else {
tvNoData.visibility = View.GONE
rvTestingPlans.visibility = View.VISIBLE
}
} else {
Log.e(TAG, "获取检测计划失败: ${response.message()}")
}
} catch (e: Exception) {
Log.e(TAG, "加载检测计划异常", e)
}
}
}
private fun showAddTestingPlanDialog() {
val dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_add_testing_plan, null)
val dialog = AlertDialog.Builder(this)
.setView(dialogView)
.create()
val spinnerDeviceId = dialogView.findViewById<Spinner>(R.id.spinnerDeviceId)
val etLocation = dialogView.findViewById<EditText>(R.id.etLocation)
val spinnerFrequency = dialogView.findViewById<Spinner>(R.id.spinnerFrequency)
val etStartTime = dialogView.findViewById<EditText>(R.id.etStartTime)
val etEndTime = dialogView.findViewById<EditText>(R.id.etEndTime)
val btnCancel = dialogView.findViewById<Button>(R.id.btnCancel)
val btnConfirm = dialogView.findViewById<Button>(R.id.btnConfirm)
// 设置设备下拉列表
val deviceAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
devices.map { "${it.deviceId} - ${it.location}" }
)
deviceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerDeviceId.adapter = deviceAdapter
// 设置频率下拉列表
val frequencyAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
arrayOf("月", "季度", "半年", "年")
)
frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerFrequency.adapter = frequencyAdapter
// 设备选择监听器
spinnerDeviceId.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (position < devices.size) {
etLocation.setText(devices[position].location)
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
// 设置时间选择
etStartTime.setOnClickListener {
showDateTimePicker { dateTime ->
etStartTime.setText(dateFormat.format(dateTime.time))
}
}
etEndTime.setOnClickListener {
showDateTimePicker { dateTime ->
etEndTime.setText(dateFormat.format(dateTime.time))
}
}
btnCancel.setOnClickListener {
dialog.dismiss()
}
btnConfirm.setOnClickListener {
val selectedDeviceIndex = spinnerDeviceId.selectedItemPosition
if (selectedDeviceIndex < 0 || selectedDeviceIndex >= devices.size) {
Toast.makeText(this, "请选择设备", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val startTimeText = etStartTime.text.toString()
if (startTimeText.isEmpty()) {
Toast.makeText(this, "请选择开始时间", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val startTimeIso = convertToIsoFormat(startTimeText)
val endTimeText = etEndTime.text.toString()
val endTimeIso = if (endTimeText.isNotEmpty()) convertToIsoFormat(endTimeText) else null
val newPlan = TestingPlan(
deviceId = devices[selectedDeviceIndex].deviceId,
location = etLocation.text.toString(),
frequency = spinnerFrequency.selectedItem.toString(),
startTime = startTimeIso,
endTime = endTimeIso
)
// 提交新计划
addTestingPlan(newPlan)
dialog.dismiss()
}
dialog.show()
}
private fun showDateTimePicker(callback: (Calendar) -> Unit) {
val calendar = Calendar.getInstance()
DatePickerDialog(
this,
{ _, year, month, dayOfMonth ->
calendar.set(Calendar.YEAR, year)
calendar.set(Calendar.MONTH, month)
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
TimePickerDialog(
this,
{ _, hourOfDay, minute ->
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
calendar.set(Calendar.MINUTE, minute)
calendar.set(Calendar.SECOND, 0)
callback(calendar)
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show()
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun addTestingPlan(plan: TestingPlan) {
lifecycleScope.launch {
try {
Log.d(TAG, "发送的检测计划数据: $plan")
val response = RetrofitClient.instance.addTestingPlan(plan)
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "添加检测计划成功", Toast.LENGTH_SHORT).show()
loadTestingPlans()
} else {
Toast.makeText(this@TestingPlanListActivity, "添加检测计划失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "添加检测计划异常", e)
Toast.makeText(this@TestingPlanListActivity, "网络错误", Toast.LENGTH_SHORT).show()
}
}
}
private fun showEditTestingPlanDialog(plan: TestingPlan) {
val dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_add_testing_plan, null)
val dialog = AlertDialog.Builder(this)
.setView(dialogView)
.create()
val spinnerDeviceId = dialog.findViewById<Spinner>(R.id.spinnerDeviceId)
val etLocation = dialog.findViewById<EditText>(R.id.etLocation)
val spinnerFrequency = dialog.findViewById<Spinner>(R.id.spinnerFrequency)
val etStartTime = dialog.findViewById<EditText>(R.id.etStartTime)
val etEndTime = dialog.findViewById<EditText>(R.id.etEndTime)
val btnCancel = dialog.findViewById<Button>(R.id.btnCancel)
val btnConfirm = dialog.findViewById<Button>(R.id.btnConfirm)
// 设置设备下拉列表
val deviceAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
devices.map { "${it.deviceId} - ${it.location}" }
)
deviceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerDeviceId.adapter = deviceAdapter
// 设置频率下拉列表
val frequencyAdapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
arrayOf("月", "季度", "半年", "年")
)
frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerFrequency.adapter = frequencyAdapter
// 填充现有数据
val devicePosition = devices.indexOfFirst { it.deviceId == plan.deviceId }
if (devicePosition >= 0) {
spinnerDeviceId.setSelection(devicePosition)
}
etLocation.setText(plan.location)
val frequencyPosition = arrayOf("月", "季度", "半年", "年").indexOf(plan.frequency)
if (frequencyPosition >= 0) {
spinnerFrequency.setSelection(frequencyPosition)
}
etStartTime.setText(convertFromIsoFormat(plan.startTime))
if (!plan.endTime.isNullOrEmpty()) {
etEndTime.setText(convertFromIsoFormat(plan.endTime))
}
// 设置时间选择
etStartTime.setOnClickListener {
showDateTimePicker { dateTime ->
etStartTime.setText(dateFormat.format(dateTime.time))
}
}
etEndTime.setOnClickListener {
showDateTimePicker { dateTime ->
etEndTime.setText(dateFormat.format(dateTime.time))
}
}
btnCancel.setOnClickListener {
dialog.dismiss()
}
btnConfirm.setOnClickListener {
val selectedDeviceIndex = spinnerDeviceId.selectedItemPosition
if (selectedDeviceIndex < 0 || selectedDeviceIndex >= devices.size) {
Toast.makeText(this, "请选择设备", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val startTimeText = etStartTime.text.toString()
if (startTimeText.isEmpty()) {
Toast.makeText(this, "请选择开始时间", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val startTimeIso = convertToIsoFormat(startTimeText)
val endTimeText = etEndTime.text.toString()
val endTimeIso = if (endTimeText.isNotEmpty()) convertToIsoFormat(endTimeText) else null
val updatedPlan = plan.copy(
deviceId = devices[selectedDeviceIndex].deviceId,
location = etLocation.text.toString(),
frequency = spinnerFrequency.selectedItem.toString(),
startTime = startTimeIso,
endTime = endTimeIso
)
updateTestingPlan(updatedPlan)
dialog.dismiss()
}
dialog.show()
}
private fun updateTestingPlan(plan: TestingPlan) {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.updateTestingPlan(plan)
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "更新检测计划成功", Toast.LENGTH_SHORT).show()
loadTestingPlans()
} else {
Toast.makeText(this@TestingPlanListActivity, "更新检测计划失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "更新检测计划异常", e)
Toast.makeText(this@TestingPlanListActivity, "网络错误", Toast.LENGTH_SHORT).show()
}
}
}
private fun showDeleteConfirmDialog(plan: TestingPlan) {
AlertDialog.Builder(this)
.setTitle("确认删除")
.setMessage("确定要删除这个检测计划吗?")
.setPositiveButton("删除") { _, _ ->
deleteTestingPlan(plan)
}
.setNegativeButton("取消", null)
.show()
}
private fun deleteTestingPlan(plan: TestingPlan) {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.deleteTestingPlan(plan.planId!!)
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "删除检测计划成功", Toast.LENGTH_SHORT).show()
loadTestingPlans()
} else {
Toast.makeText(this@TestingPlanListActivity, "删除检测计划失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "删除检测计划异常", e)
Toast.makeText(this@TestingPlanListActivity, "网络错误", Toast.LENGTH_SHORT).show()
}
}
}
private fun togglePlanStatus(plan: TestingPlan) {
val newStatus = when (plan.status) {
"待启用" -> "启用"
"启用" -> "停用"
"停用" -> "启用"
else -> "启用"
}
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.updateTestingPlanStatus(plan.planId!!, newStatus)
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "状态更新成功", Toast.LENGTH_SHORT).show()
loadTestingPlans()
} else {
Toast.makeText(this@TestingPlanListActivity, "状态更新失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "更新状态异常", e)
Toast.makeText(this@TestingPlanListActivity, "网络错误", Toast.LENGTH_SHORT).show()
}
}
}
private fun enablePlan(plan: TestingPlan) {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.updateTestingPlanStatus(plan.planId!!, "启用")
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "状态更新成功", Toast.LENGTH_SHORT).show()
// 启用成功后生成对应的检测工单
generateTestingOrder(plan.planId!!)
} else {
Toast.makeText(this@TestingPlanListActivity, "状态更新失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "更新状态异常", e)
Toast.makeText(this@TestingPlanListActivity, "网络错误", Toast.LENGTH_SHORT).show()
}
}
}
private fun disablePlan(plan: TestingPlan) {
updatePlanStatus(plan, "停用")
}
private fun updatePlanStatus(plan: TestingPlan, newStatus: String) {
lifecycleScope.launch {
try {
val response = RetrofitClient.instance.updateTestingPlanStatus(plan.planId!!, newStatus)
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "状态更新成功", Toast.LENGTH_SHORT).show()
loadTestingPlans()
} else {
Toast.makeText(this@TestingPlanListActivity, "状态更新失败", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e(TAG, "更新状态异常", e)
Toast.makeText(this@TestingPlanListActivity, "网络错误", Toast.LENGTH_SHORT).show()
}
}
}
private fun convertToIsoFormat(dateTimeString: String): String {
return try {
val date = dateFormat.parse(dateTimeString)
val isoFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault())
isoFormat.format(date!!)
} catch (e: Exception) {
dateTimeString
}
}
private fun convertFromIsoFormat(isoString: String): String {
return try {
val isoFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault())
val date = isoFormat.parse(isoString)
dateFormat.format(date!!)
} catch (e: Exception) {
isoString
}
}
// 生成检测工单
private fun generateTestingOrder(planId: Int) {
lifecycleScope.launch {
try {
val request = mapOf("planIds" to listOf(planId))
val gson = Gson()
val json = gson.toJson(request)
val requestBody = json.toRequestBody("application/json".toMediaTypeOrNull())
val response = RetrofitClient.instance.generateTestingOrders(requestBody)
if (response.isSuccessful) {
Toast.makeText(this@TestingPlanListActivity, "启用成功,已生成检测工单", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@TestingPlanListActivity, "启用成功,但工单生成失败", Toast.LENGTH_SHORT).show()
}
// 重新加载检测计划列表
loadTestingPlans()
} catch (e: Exception) {
Log.e(TAG, "生成工单异常", e)
Toast.makeText(this@TestingPlanListActivity, "生成工单失败: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
// RecyclerView Adapter
class TestingPlanAdapter(
private val plans: MutableList<TestingPlan>,
private val onItemAction: (TestingPlan, String) -> Unit
) : RecyclerView.Adapter<TestingPlanAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvPlanId: TextView = itemView.findViewById(R.id.tvPlanId)
val tvDeviceId: TextView = itemView.findViewById(R.id.tvDeviceId)
val tvLocation: TextView = itemView.findViewById(R.id.tvLocation)
val tvFrequency: TextView = itemView.findViewById(R.id.tvFrequency)
val tvStatus: TextView = itemView.findViewById(R.id.tvStatus)
val tvTimeRange: TextView = itemView.findViewById(R.id.tvTimeRange)
val btnEnable: Button = itemView.findViewById(R.id.btnEnable)
val btnDisable: Button = itemView.findViewById(R.id.btnDisable)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_testing_plan, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val plan = plans[position]
holder.tvPlanId.text = "计划ID: ${plan.planId ?: position + 1}"
holder.tvDeviceId.text = "设备ID: ${plan.deviceId}"
holder.tvLocation.text = "检测位置: ${plan.location}"
holder.tvFrequency.text = "检测频率: ${plan.frequency}"
holder.tvStatus.text = "状态: ${plan.status}"
// 格式化时间范围
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val isoFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault())
val startTimeStr = try {
val startDate = isoFormat.parse(plan.startTime)
dateFormat.format(startDate!!)
} catch (e: Exception) {
plan.startTime.substring(0, 10) // 取前10位作为日期
}
val endTimeStr = if (!plan.endTime.isNullOrEmpty()) {
try {
val endDate = isoFormat.parse(plan.endTime)
dateFormat.format(endDate!!)
} catch (e: Exception) {
plan.endTime.substring(0, 10)
}
} else {
"无限期"
}
holder.tvTimeRange.text = "时间范围: $startTimeStr ~ $endTimeStr"
// 根据状态设置颜色
when (plan.status) {
"启用" -> holder.tvStatus.setTextColor(0xFF4CAF50.toInt())
"停用" -> holder.tvStatus.setTextColor(0xFFF44336.toInt())
"待启用" -> holder.tvStatus.setTextColor(0xFFFF9800.toInt())
}
// 设置按钮点击事件
holder.btnEnable.setOnClickListener {
onItemAction(plan, "enable")
}
holder.btnDisable.setOnClickListener {
onItemAction(plan, "disable")
}
// 根据当前状态调整按钮可用性
when (plan.status) {
"启用" -> {
holder.btnEnable.isEnabled = false
holder.btnDisable.isEnabled = true
}
"停用", "待启用" -> {
holder.btnEnable.isEnabled = true
holder.btnDisable.isEnabled = false
}
}
}
override fun getItemCount() = plans.size
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvOrderId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="工单编号: 1"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvFaultId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="故障编号: 1" />
<TextView
android:id="@+id/tvStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="状态: 处理中" />
<TextView
android:id="@+id/tvRepairDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="维修描述: 暂无" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvFaultId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="故障编号: 1"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvDeviceId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="设备编号: FIRE001" />
<TextView
android:id="@+id/tvFaultDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="故障描述: 喷淋系统水压异常" />
<TextView
android:id="@+id/tvReportType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="报修类型: 电话报修" />
<TextView
android:id="@+id/tvReportedBy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="报修人: 张三" />
<TextView
android:id="@+id/tvReportedPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="联系电话: 13800000000" />
<Button
android:id="@+id/btnTakeTask"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="接取任务" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvPlanId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="计划ID: 1"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvDeviceId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="设备ID: DEV001"
android:textSize="14sp" />
<TextView
android:id="@+id/tvLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="检测位置:"
android:textSize="14sp" />
<TextView
android:id="@+id/tvFrequency"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="检测频率: 月"
android:textSize="14sp" />
<TextView
android:id="@+id/tvStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="状态: 启用"
android:textSize="14sp" />
<TextView
android:id="@+id/tvTimeRange"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="时间范围: 2024-01-01 ~ 2024-12-31"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<Button
android:id="@+id/btnEnable"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:text="启用" />
<Button
android:id="@+id/btnDisable"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停用" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 添加工单类型选择下拉框 -->
<Spinner
android:id="@+id/taskTypeSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/taskTypeSpinner"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="8dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/tvEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无待处理任务"
android:textSize="18sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

浙公网安备 33010602011771号