文档管理中心
FAQ应用框架开发UI框架组件使用搜索建议需要点击两次才会消失

搜索建议需要点击两次才会消失

问题现象

在搜索框组件中,当用户输入内容触发搜索建议时,下拉列表需要点击两次才会消失。正常情况下,点击一次即可关闭下拉列表。该问题导致用户体验不一致,且不符合常规交互预期。

背景知识

问题定位

检查搜索建议点击事件回调函数,确认回调函数是否通过代码逻辑区分自动填充与手动输入,一般可通过标志位进行区分,标志位是一个变量,用于标记程序的某种状态或条件,控制代码的执行逻辑。比如在下方代码中,注释位置未使用标志位来区分自动填充与手动输入。

收起
自动换行
深色代码主题
复制
  1. List() {
  2. ForEach(this.filteredSuggestions, (item: string) => {
  3. ListItem() {
  4. Text(item)
  5. .width('100%')
  6. .height(50)
  7. .fontSize(18)
  8. .textAlign(TextAlign.Start)
  9. .padding({ left: 15 })
  10. }
  11. .onClick(() => {
  12. // 未设置标志位,表示本次填充为自动填充
  13. this.controller.deleteText();
  14. this.controller.addText(item);
  15. this.controller.caretPosition(item.length);
  16. })
  17. }, (item: string) => item)
  18. }
  19. .width('90%')
  20. .border({ width: 1, color: '#e0e0e0' })
  21. .borderRadius(8)
  22. .shadow({ radius: 6, color: '#20000000', offsetX: 2, offsetY: 4 })
  23. .margin({ top: 5 })

分析结论

点击搜索建议,自动填充进搜索框后,仍将该自动填充判断为用户输入,再次对该输入进行了匹配搜索,因此展示了同样的搜索建议。

修改建议

在点击搜索建议后,在注释位置设置标志位,表示本次填充为自动填充:

收起
自动换行
深色代码主题
复制
  1. @Entry
  2. @Component
  3. struct Input {
  4. private controller: TextInputController = new TextInputController();
  5. @State inputText: string = '';
  6. @State filteredSuggestions: string[] = [];
  7. @State showSuggestions: boolean = false;
  8. private isProgrammaticChange: boolean = false;
  9. private suggestions: string[] = ['Apple', 'Banana', 'Cherry'];
  10. build() {
  11. Column() {
  12. TextInput({ controller: this.controller , placeholder:'请输入水果名称'})
  13. .width('90%')
  14. .height(40)
  15. .onChange((value: string) => {
  16. if (this.isProgrammaticChange) {
  17. this.isProgrammaticChange = false;
  18. return;
  19. }
  20. this.inputText = value;
  21. if (value.length > 0) {
  22. this.filterSuggestions();
  23. } else {
  24. this.showSuggestions = false;
  25. }
  26. })
  27. if (this.showSuggestions && this.filteredSuggestions.length > 0) {
  28. List() {
  29. ForEach(this.filteredSuggestions, (item: string) => {
  30. ListItem() {
  31. Text(item)
  32. .fontSize(16)
  33. .padding(10)
  34. }
  35. .onClick(() => {
  36. this.isProgrammaticChange = true;
  37. this.controller.deleteText();
  38. this.controller.addText(item);
  39. this.controller.caretPosition(item.length);
  40. this.showSuggestions = false;
  41. })
  42. })
  43. }
  44. .width('90%')
  45. .border({ width: 1, color: '#ccc' })
  46. .backgroundColor(Color.White)
  47. }
  48. }
  49. .width('100%')
  50. .padding(20)
  51. }
  52. private filterSuggestions() {
  53. const input = this.inputText.toLowerCase();
  54. this.filteredSuggestions = this.suggestions.filter(item =>
  55. item.toLowerCase().startsWith(input)
  56. );
  57. this.showSuggestions = this.filteredSuggestions.length > 0;
  58. }
  59. }
在 FAQ 中进行搜索
请输入您想要搜索的关键词