From 147c66adbb642ceb7c64cbc714cee5c4d599c943 Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Wed, 26 Aug 2026 11:12:32 +0800 Subject: [PATCH] feat(agent): add #93 search clear action --- android/app/build.gradle.kts | 4 +- .../goauto/agent/ui/TaskHistoryFragment.kt | 42 +++++++++++++++++-- .../src/main/res/drawable/ic_agent_clear.xml | 13 ++++++ .../goauto/agent/TaskNumberParserTest.kt | 10 +++++ 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_agent_clear.xml diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index eeab937..3051e00 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -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" diff --git a/android/app/src/main/java/cn/ilapage/goauto/agent/ui/TaskHistoryFragment.kt b/android/app/src/main/java/cn/ilapage/goauto/agent/ui/TaskHistoryFragment.kt index ff07718..f006280 100644 --- a/android/app/src/main/java/cn/ilapage/goauto/agent/ui/TaskHistoryFragment.kt +++ b/android/app/src/main/java/cn/ilapage/goauto/agent/ui/TaskHistoryFragment.kt @@ -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() } diff --git a/android/app/src/main/res/drawable/ic_agent_clear.xml b/android/app/src/main/res/drawable/ic_agent_clear.xml new file mode 100644 index 0000000..28d87ed --- /dev/null +++ b/android/app/src/main/res/drawable/ic_agent_clear.xml @@ -0,0 +1,13 @@ + + + diff --git a/android/app/src/test/java/cn/ilapage/goauto/agent/TaskNumberParserTest.kt b/android/app/src/test/java/cn/ilapage/goauto/agent/TaskNumberParserTest.kt index bb8fd95..0b01fbf 100644 --- a/android/app/src/test/java/cn/ilapage/goauto/agent/TaskNumberParserTest.kt +++ b/android/app/src/test/java/cn/ilapage/goauto/agent/TaskNumberParserTest.kt @@ -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")) + } }