feat(agent): add #93 search clear action

This commit is contained in:
QiuSW
2026-08-26 11:12:32 +08:00
parent 7b6cc00503
commit 147c66adbb
4 changed files with 64 additions and 5 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId = "cn.ilapage.goauto.agent"
minSdk = 23
targetSdk = 34
versionCode = 7
versionName = "0.5.0"
versionCode = 8
versionName = "0.5.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -2,6 +2,8 @@ package cn.ilapage.goauto.agent.ui
import android.content.res.ColorStateList
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
@@ -24,6 +26,8 @@ import cn.ilapage.goauto.agent.service.AgentForegroundService
import cn.ilapage.goauto.agent.service.AgentSettingsStore
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import java.util.Locale
import java.util.UUID
@@ -43,6 +47,10 @@ internal object TaskNumberParser {
}
}
internal object TaskSearchInputPolicy {
fun shouldShowClear(value: CharSequence?): Boolean = !value.isNullOrEmpty()
}
internal object CollectionResetPolicy {
private val terminalStatuses = setOf("completed", "completed_partial", "failed")
@@ -94,7 +102,16 @@ class TaskHistoryFragment : Fragment() {
return context.card(context.cardColumn().apply {
setPadding(context.dp(12), context.dp(8), context.dp(12), context.dp(8))
val row = LinearLayout(context).apply { orientation = LinearLayout.HORIZONTAL; gravity = Gravity.CENTER_VERTICAL }
searchInput = EditText(context).apply {
val searchLayout = TextInputLayout(context).apply {
boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_NONE
endIconMode = TextInputLayout.END_ICON_CUSTOM
setEndIconDrawable(R.drawable.ic_agent_clear)
setEndIconTintList(ColorStateList.valueOf(context.getColor(R.color.agent_text_muted)))
endIconContentDescription = if (collection) "清除采集任务编号" else "清除采购任务编号"
isEndIconCheckable = false
isEndIconVisible = false
}
searchInput = TextInputEditText(context).apply {
hint = if (collection) "输入编号,如 35 或 #35" else "输入编号,如 12 或 CG-12"
contentDescription = if (collection) "采集任务编号" else "采购任务编号"
setHintTextColor(context.getColor(R.color.agent_text_muted))
@@ -108,7 +125,19 @@ class TaskHistoryFragment : Fragment() {
if (action == EditorInfo.IME_ACTION_SEARCH) { search(); true } else false
}
}
row.addView(searchInput, LinearLayout.LayoutParams(0, context.dp(48), 1f))
searchInput.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(value: CharSequence?, start: Int, count: Int, after: Int) = Unit
override fun onTextChanged(value: CharSequence?, start: Int, before: Int, count: Int) {
searchLayout.isEndIconVisible = TaskSearchInputPolicy.shouldShowClear(value)
}
override fun afterTextChanged(value: Editable?) = Unit
})
searchLayout.setEndIconOnClickListener { clearSearch() }
searchLayout.addView(searchInput, LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
context.dp(48),
))
row.addView(searchLayout, LinearLayout.LayoutParams(0, context.dp(48), 1f))
row.addView(MaterialButton(context).apply {
text = "搜索"
textSize = 14f
@@ -180,6 +209,13 @@ class TaskHistoryFragment : Fragment() {
load()
}
private fun clearSearch() {
searchInput.error = null
searchInput.setText("")
page = 1
load()
}
private fun load() {
if (!this::resultColumn.isInitialized) return
val context = requireContext()
@@ -405,7 +441,7 @@ class TaskHistoryFragment : Fragment() {
if (searching) "没有找到${if (collection) "采集" else "采购"}任务 ${searchInput.text}" else "暂无任务记录",
if (searching) "搜索范围仅限当前设备。请检查编号,或清空搜索查看全部记录。" else "新任务由服务端下发,Agent 会自动领取。",
if (searching) "清空搜索" else "刷新",
) { if (searching) searchInput.setText(""); page = 1; load() }
) { if (searching) clearSearch() else { page = 1; load() } }
}
private fun showError(title: String, description: String) = showMessage(title, description, "重新加载") { load() }
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/transparent"
android:pathData="M6,6L18,18M18,6L6,18"
android:strokeColor="#FFFFFFFF"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:strokeWidth="2" />
</vector>
@@ -1,9 +1,12 @@
package cn.ilapage.goauto.agent
import cn.ilapage.goauto.agent.ui.TaskNumberParser
import cn.ilapage.goauto.agent.ui.TaskSearchInputPolicy
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
import org.junit.Test
class TaskNumberParserTest {
@@ -21,4 +24,11 @@ class TaskNumberParserTest {
assertNull(TaskNumberParser.normalize(" ", true))
assertThrows(IllegalArgumentException::class.java) { TaskNumberParser.normalize("CG-abc", false) }
}
@Test fun clearIconOnlyShowsWhenInputContainsText() {
assertFalse(TaskSearchInputPolicy.shouldShowClear(null))
assertFalse(TaskSearchInputPolicy.shouldShowClear(""))
assertTrue(TaskSearchInputPolicy.shouldShowClear("#62"))
assertTrue(TaskSearchInputPolicy.shouldShowClear("CG-12"))
}
}