你好,我是华鸿技术栈的作者。
前几篇讲了状态管理的东西,比如@State、@Prop、@Link、@Provide、@Consume,这些装饰器实现了组件之间传数据、跨层级共享。
今天开始讲最基础的组件:Text 和 Image。
这两个组件是最常用的,其中有写问题单独讲一讲:Text 文字太长怎么处理、Image 图片加载失败显示什么、本地图片放哪个目录,最后做一个文章卡片的小练习。
10.1 Text——超长文字怎么截断
显示一行文字,最简单:
但页面上的文字很少刚好装得下。标题太长了怎么办?写 CSS 的时候得写一大串:overflow: hidden; text-overflow: ellipsis; white-space: nowrap; 还得考虑浏览器兼容,多行截断更麻烦。ArkTS 这边思路一样,只是写法不同,两个属性就搞定了:maxLines 和 textOverflow。
Text('这是一个非常长的标题文字,可能会超过容器宽度,需要控制行数和省略方式') .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) .width('100%')
maxLines(2) 最多显示两行,textOverflow 超出部分打省略号。width 必须指定,不给宽度文字不知道在哪截断。比写css简介多了,根本不用记那么多css属性。这也是鸿蒙原生组件进化的地方,最多显示几行,超出部分打省略号是前端开发最常见的需求,直接内核实现了。
字号、颜色、粗细不展开写了,fontSize,fontColor,fontWeight,熟悉css的一猜就知道了,基本上不用记忆:
Text('标题') .fontSize(20) // 字号,单位vp .fontColor('#333333') // 十六进制颜色 .fontWeight(FontWeight.Bold) // 粗细
还有种情况:一段文字里混用不同样式,比如作者信息栏里“作者”是灰色,“华鸿技术栈”是黑色加粗。用 Span 嵌套:
Text() { Span('作者:') .fontSize(14) .fontColor('#666666') Span('华鸿技术栈') .fontSize(14) .fontWeight(FontWeight.Bold) .fontColor('#333333')}
用了 Span 之后,Text 不直接传字符串,改成大括号包裹子组件。
10.2 Image——几个容易调不出来的问题
Image 支持 PNG、JPG、BMP、SVG、GIF。语法一行:
Image($r('app.media.icon')) .width(100) .height(100)
实际写的时候,下面几个问题问要注意:
本地图片放哪个目录
放在 entry/src/main/resources/base/media/,其他地方不行。
引用用 $r('app.media.文件名'),不带后缀。文件名叫 icon.png,写 app.media.icon 就行,写 app.media.icon.png 反而找不到。
图片放错目录,编译不报错,运行时图片位置一片空白。跑起来发现某个图片不显示,打开 media 目录看一眼文件到底在不在,十次有八次是目录放错了或者文件名写错了。
网络图片不显示
Image('https://example.com/avatar.jpg') .width(100) .height(100)
网络图片出不来,先检查 module.json5 里有没有这个:
"requestPermissions": [ { "name": "ohos.permission.INTERNET" }]
没申请权限,图片不会报错,就是加载不出来。初学者不知道这种设置,控制台没有任何跟 Image 相关的报错,URL 复制到浏览器也能打开,但模拟器上就是一片白。可能调了半天也不知道原因。
这点其实很像Chrom插件的配置模式。
图片变形怎么处理
图片宽高跟你设的容器尺寸一般不对等,用 objectFit 控制缩放:
// Contain:等比缩放,图片完整显示,容器可能留白Image($r('app.media.photo')) .objectFit(ImageFit.Contain)// Cover:等比缩放,填满容器,超出部分裁掉(默认就是这个)Image($r('app.media.photo')) .objectFit(ImageFit.Cover)// Fill:拉伸填满,不等比,图片可能变形Image($r('app.media.photo')) .objectFit(ImageFit.Fill)
头像的常见写法:
Image($r('app.media.avatar')) .width(80) .height(80) .objectFit(ImageFit.Cover) .borderRadius(40) // 宽高一半,切成圆形
加载失败显示什么
网络图片加载失败或者本地图片没找到,默认什么都不显示。用 alt 设一个占位图:
Image('https://example.com/avatar.jpg') .width(100) .height(100) .alt($r('app.media.placeholder'))
占位图也要放在 media 目录下。
10.3 拼一个文章卡片
把 Text 和 Image 拼一起,做个文章列表里常见的卡片——左侧封面图,右侧标题、摘要、阅读量。
@Entry@Componentstruct ArticleCard { build() { Row() { // 左侧封面图 Image($r('app.media.cover')) .width(100) .height(80) .objectFit(ImageFit.Cover) .borderRadius(8) // 右侧文字区域 Column({ space: 6 }) { Text('鸿蒙原生应用开发实战:从零搭建一个完整App') .fontSize(16) .fontWeight(FontWeight.Medium) .fontColor('#333333') .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) Text('分享实战代码、源码解析、性能优化及生态前沿,不讲虚的只上干货') .fontSize(13) .fontColor('#999999') .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) Row() { Text('华鸿技术栈') .fontSize(12) .fontColor('#666666') Text(' · ') .fontSize(12) .fontColor('#CCCCCC') Text('1280阅读') .fontSize(12) .fontColor('#666666') } } .layoutWeight(1) .margin({ left: 12 }) .alignItems(HorizontalAlign.Start) } .width('100%') .padding(16) .borderRadius(12) .backgroundColor(Color.White) }}
代码里 $r('app.media.cover') 需要你在 entry/src/main/resources/base/media/ 里放一张 cover.png。没放图片 Image 区域空白,其他部分正常渲染。
常见问题
Q: Text 文字太长怎么显示省略号?A: maxLines 设行数,textOverflow 设省略号,width 给宽度。三个缺一不可,漏了 width 文字没有截断边界。
Q: Image 本地图片放哪个目录?A: entry/src/main/resources/base/media/。引用 $r('app.media.文件名'),不带后缀。
Q: 网络图片加载不出来怎么排查?A: 两步。第一看 module.json5 里有没有 ohos.permission.INTERNET。第二看图片 URL 在浏览器能不能打开。权限问题最常见。
Q: 图片变形了怎么办?A: 用 objectFit。头像 Cover + borderRadius 切圆,需要完整显示用 Contain。别用 Fill。
Q: 图片加载失败显示空白怎么办?A: alt 设占位图,加载失败自动显示。
下一篇:Button 和 TextInput。按钮的几种样式,输入框的类型控制和内容获取,四个基础组件凑齐,搭一个完整的登录页面。
本文由「华鸿技术栈」原创发布,专注鸿蒙原生应用与元服务开发。分享实战代码、源码解析、性能优化及生态前沿。不讲虚的,只上干货。转载请联系授权。
#鸿蒙开发 #ArkTS #ArkUI #Text组件 #Image组件 #鸿蒙原生应用开