文档管理中心
FAQ应用框架开发UI框架组件使用如何自定义一个既可输入也可下拉选择的文本行

如何自定义一个既可输入也可下拉选择的文本行

问题现象

如何快速实现一个自定义文本框,既能自己输入文本,又能通过下拉框选择已有文本?

背景知识

TextInput组件的showUnit属性设置控件作为文本框单位。需搭配showUnderline使用,当showUnderline为true时生效。以此实现下拉框功能。

解决方案

  • 方案一:使用TextInput组件的showUnit属性,示例代码如下:
    收起
    自动换行
    深色代码主题
    复制
    1. @Entry
    2. @Component
    3. struct SelectExample {
    4. @State text: string = '请输入...';
    5. @Builder
    6. itemEnd() {
    7. Select([{ value: 'selectedOptionFont' },
    8. { value: 'optionFont' },
    9. { value: 'backgroundColor' },
    10. { value: 'responseRegion' }])
    11. .height('48vp')
    12. .borderRadius(0)
    13. .selected(2)
    14. .align(Alignment.Center)
    15. .value('选择一个词')
    16. .font({ size: 20, weight: 500 })
    17. .fontColor('#182431')
    18. .selectedOptionFont({ size: 20, weight: 400 })
    19. .optionFont({ size: 20, weight: 400 })
    20. .backgroundColor(Color.Transparent)
    21. .responseRegion({
    22. height: '40vp',
    23. width: '80%',
    24. x: '10%',
    25. y: '6vp'
    26. })
    27. .onSelect((index: number, text: string) => {
    28. console.info('Select:' + index);
    29. this.text = text;
    30. })
    31. }
    32. build() {
    33. Column() {
    34. TextInput({ placeholder: 'underline style', text: this.text })
    35. .showUnderline(true)
    36. .width(350)
    37. .height(60)
    38. .showUnit(this.itemEnd) // 设置文本下拉框
    39. }.width('100%')
    40. }
    41. }

    效果预览:

  • 方案二:组合使用Stack组件和margin属性自定义实现,示例代码:
    收起
    自动换行
    深色代码主题
    复制
    1. @Entry
    2. @Component
    3. struct SelectExample2 {
    4. @State selectVal: undefined = undefined;
    5. @State currentSearchContent: string | undefined = '';
    6. private controller = new TextInputController();
    7. build() {
    8. Column() {
    9. Stack() {
    10. // 输入框组件
    11. TextInput({ placeholder: '请输入内容', controller: this.controller, text: this.currentSearchContent })
    12. .height(40)
    13. .width('100%')
    14. .fontSize(16)
    15. .placeholderColor(Color.Grey)
    16. .placeholderFont({ size: 16, weight: 400 })
    17. .borderStyle(BorderStyle.Solid)
    18. .backgroundColor('#E6E8E9')
    19. Row() {
    20. // 下拉框组件
    21. Select([
    22. { value: 'aaa' },
    23. { value: 'bbb' },
    24. { value: 'ccc' },
    25. { value: 'ddd' }
    26. ])
    27. .value(this.selectVal!!)
    28. .font({ size: 16, weight: 500 })
    29. .selectedOptionFont({ size: 16, weight: 400 })
    30. .optionFont({ size: 16, weight: 400 })
    31. .menuAlign(MenuAlignType.START, { dx: -260, dy: 0 })
    32. .optionWidth(200)
    33. .optionHeight(200)
    34. .backgroundColor('#E6E8E9')
    35. .onSelect((index: number, text?: string | undefined) => {
    36. this.selectVal = undefined;
    37. this.currentSearchContent = text;
    38. console.info('index:', index);
    39. })
    40. // 自定义图标
    41. Image($r('app.media.startIcon'))
    42. .width(24)
    43. .height(24)
    44. .margin({ left: -36 })
    45. .hitTestBehavior(HitTestMode.Transparent)
    46. }
    47. .width('100%')
    48. .hitTestBehavior(HitTestMode.None)
    49. .justifyContent(FlexAlign.End)
    50. .padding({ right: '10' })
    51. }
    52. .padding({ left: 16, right: 16 })
    53. .alignContent(Alignment.Start)
    54. .width('100%')
    55. }
    56. .width('100%')
    57. .height('100%')
    58. .backgroundColor($r('sys.color.icon_on_primary'))
    59. }
    60. }

    效果预览:

在 FAQ 中进行搜索
请输入您想要搜索的关键词