ArkUI TextArea:多行输入别放飞,长内容也能乖乖待住

举报
蓝瘦的蜕变 发表于 2026/08/23 21:00:11 2026/08/23
【摘要】 这篇我们写 TextArea。它看起来只是 TextInput 的多行版本,但真放到页面里,问题会马上冒出来:高度被撑乱、字数没边界、滚动条不好看、禁用态像还能编辑。 所以这个案例不做评论发布,也不做草稿保存。我们只把多行输入框本身处理顺:占位提示、字数计数、最多行数、滚动条、高度适配和禁用态。 参考文档: https

ArkUI TextArea:多行输入别放飞,长内容也能乖乖待住

这篇我们写 TextArea。它看起来只是 TextInput 的多行版本,但真放到页面里,问题会马上冒出来:高度被撑乱、字数没边界、滚动条不好看、禁用态像还能编辑。

所以这个案例不做评论发布,也不做草稿保存。我们只把多行输入框本身处理顺:占位提示、字数计数、最多行数、滚动条、高度适配和禁用态。

参考文档:

  • https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkui
  • https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-development

多行输入先给够空间

TextArea 常见在反馈、备注、评论、需求说明这些地方。它和单行输入最大的区别不是“能换行”,而是你要提前给它一个稳定的区域。

TextArea({ placeholder: '写下你遇到的问题,越具体越好' })
  .width('100%')
  .height(128)
  .fontSize(15)
  .fontColor('#0F172A')
  .placeholderColor('#94A3B8')
  .placeholderFont({ size: 14, weight: 400 })
  .caretColor('#2563EB')
  .backgroundColor('#FFFFFF')
  .border({ width: 1, color: '#CBD5E1' })
  .borderRadius(8)
  .padding({ left: 12, right: 12, top: 10, bottom: 10 })

这里直接给了 height(128)。多行输入别一开始就让它跟内容疯狂长高,新手页面很容易因此被撑散。

占位文字仍然放轻。长输入框里如果提示文字太黑,会让人误以为里面已经有内容。

字数限制要让用户看见

长文本最需要边界。maxLength 负责限制长度,showCounter(true) 负责把这个边界摆给用户看。

TextArea({ text: '页面整体不错,但这里我希望能补一个更明显的加载状态。', placeholder: '请输入留言' })
  .maxLength(80)
  .showCounter(true)

这个组合很适合留言、反馈、备注。用户不用猜还能写多少,也不会写到最后才发现超了。

这里没有写提交按钮。不是不能写,而是这篇先讲组件本体。提交、校验、草稿保存放到后面的表单和状态章节会更清楚。

行数边界别靠感觉

如果内容可能换很多行,maxLines 要提前想好。它控制最多显示几行,超过以后就不要继续挤页面。

TextArea({
  text: '第一行:用户希望导入数据。\n第二行:导入完成后要看到成功数量。\n第三行:失败数据要能下载。\n第四行:错误原因要写清楚。',
  placeholder: '请输入需求说明'
})
  .height(116)
  .lineHeight(22)
  .maxLines(3)
  .barState(BarState.Auto)

这里故意放了四行内容,但 maxLines(3) 只让它显示三行的边界。barState(BarState.Auto) 让滚动条按需要出现,不用一直挂在旁边。

如果你的页面是固定表单,行数边界比“让输入框自由长高”更稳。

高度适配也要说清优先级

heightAdaptivePolicy 用来指定高度适配策略。案例里用的是 TextHeightAdaptivePolicy.MAX_LINES_FIRST,意思是先考虑最大行数。

TextArea({ placeholder: '输入较长说明时,先按 maxLines 处理高度边界' })
  .height(118)
  .maxLines(4)
  .heightAdaptivePolicy(TextHeightAdaptivePolicy.MAX_LINES_FIRST)

这个属性不用每个 TextArea 都写。我们在案例里放出来,是为了让你知道:当高度、行数、内容同时出现时,ArkUI 不是只能靠固定高度硬撑。

禁用态要安静

不能编辑的多行内容,别还做得像一个等待输入的框。

TextArea({ text: '当前记录已经提交审核,备注内容暂时不能修改。', placeholder: '审核备注' })
  .enabled(false)
  .backgroundColor('#E2E8F0')
  .fontColor('#64748B')

enabled(false) 负责禁用交互,颜色负责告诉用户“这里现在不能改”。这俩最好一起做。

看案例时盯这几处

打开案例页后,可以顺着这几个点看:

  • 第一块基础 TextArea 的高度是否稳定。
  • 留言区是否显示字数计数。
  • 需求说明是否按 maxLines 控制显示边界。
  • 高度适配示例是否和普通固定高度示例有区别。
  • 禁用态是否明显不能编辑。

这篇不跑 hvigor。你在 DevEco Studio 里打开案例页,点进几个多行输入框,重点看高度、换行和计数显示。

如果你项目里有“反馈内容”或“备注说明”,可以先把 maxLengthshowCounter 补上。你们平时最容易失控的是评论框、备注框,还是需求说明这种长字段?

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/basic/ArkUITextAreaDemo.ets

@Entry
@Component
struct ArkUITextAreaDemo {
  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 4 }) {
      Text(title)
        .width('100%')
        .fontSize(16)
        .fontWeight(700)
        .fontColor('#0F172A')

      Text(desc)
        .width('100%')
        .fontSize(13)
        .fontColor('#64748B')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  inputLabel(label: string) {
    Text(label)
      .width('100%')
      .fontSize(13)
      .fontWeight(600)
      .fontColor('#334155')
  }

  build() {
    Scroll() {
      Column({ space: 18 }) {
        Text('ArkUI TextArea')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .fontColor('#0F172A')

        Text('多行输入别放飞,长内容也能乖乖待住')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('这一页只看 TextArea 自己:多行占位、字数限制、计数提示、滚动条、行数边界和禁用态。评论提交、草稿保存这些业务逻辑先不塞进来。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('先让多行输入看起来安静', 'TextArea 适合备注、评论、反馈这类长一点的内容,区域要够高,提示文字也别太抢眼。')

          this.inputLabel('反馈内容')

          TextArea({ placeholder: '写下你遇到的问题,越具体越好' })
            .width('100%')
            .height(128)
            .fontSize(15)
            .fontColor('#0F172A')
            .placeholderColor('#94A3B8')
            .placeholderFont({ size: 14, weight: 400 })
            .caretColor('#2563EB')
            .backgroundColor('#FFFFFF')
            .border({ width: 1, color: '#CBD5E1' })
            .borderRadius(8)
            .padding({ left: 12, right: 12, top: 10, bottom: 10 })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F8FAFC')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('长内容要给边界', '多行输入最怕无限写下去。maxLength 配合 showCounter,用户能提前知道还剩多少空间。')

          this.inputLabel('留言')

          TextArea({ text: '页面整体不错,但这里我希望能补一个更明显的加载状态。', placeholder: '请输入留言' })
            .width('100%')
            .height(132)
            .fontSize(15)
            .fontColor('#0F172A')
            .placeholderColor('#94A3B8')
            .caretColor('#0F766E')
            .maxLength(80)
            .showCounter(true)
            .backgroundColor('#FFFFFF')
            .border({ width: 1, color: '#99F6E4' })
            .borderRadius(8)
            .padding({ left: 12, right: 12, top: 10, bottom: 10 })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F0FDFA')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('行数别让布局跟着乱跳', 'maxLines 控制最多显示几行,超出的内容可以滚动看;滚动条用 Auto 就够了。')

          this.inputLabel('需求说明')

          TextArea({
            text: '第一行:用户希望导入数据。\n第二行:导入完成后要看到成功数量。\n第三行:失败数据要能下载。\n第四行:错误原因要写清楚。',
            placeholder: '请输入需求说明'
          })
            .width('100%')
            .height(116)
            .fontSize(15)
            .fontColor('#0F172A')
            .lineHeight(22)
            .placeholderColor('#94A3B8')
            .caretColor('#7C3AED')
            .maxLines(3)
            .barState(BarState.Auto)
            .backgroundColor('#FFFFFF')
            .border({ width: 1, color: '#DDD6FE' })
            .borderRadius(8)
            .padding({ left: 12, right: 12, top: 10, bottom: 10 })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F5F3FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('自适应高度要配合行数看', 'heightAdaptivePolicy 可以指定高度适配策略,案例里用最大行数优先,让多行内容先按行数边界处理。')

          this.inputLabel('自动说明')

          TextArea({ placeholder: '输入较长说明时,先按 maxLines 处理高度边界' })
            .width('100%')
            .height(118)
            .fontSize(15)
            .fontColor('#0F172A')
            .placeholderColor('#94A3B8')
            .caretColor('#C2410C')
            .maxLines(4)
            .heightAdaptivePolicy(TextHeightAdaptivePolicy.MAX_LINES_FIRST)
            .backgroundColor('#FFFFFF')
            .border({ width: 1, color: '#FED7AA' })
            .borderRadius(8)
            .padding({ left: 12, right: 12, top: 10, bottom: 10 })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFF7ED')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('不能编辑时就别装得像能编辑', '禁用态要让用户一眼明白:这里能看,但现在不能改。')

          this.inputLabel('审核备注')

          TextArea({ text: '当前记录已经提交审核,备注内容暂时不能修改。', placeholder: '审核备注' })
            .width('100%')
            .height(104)
            .fontSize(15)
            .fontColor('#64748B')
            .enabled(false)
            .backgroundColor('#E2E8F0')
            .border({ width: 1, color: '#CBD5E1' })
            .borderRadius(8)
            .padding({ left: 12, right: 12, top: 10, bottom: 10 })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E2E8F0' })
        .borderRadius(8)
      }
      .width('100%')
      .padding(20)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。