鸿蒙next 多行文字加图片后缀实现方案
需求
实现类似iOS的YYLabel之类的在文字后面加上图片作为后缀的样式,多行时文字使用…省略超出部分,但必须保证图片的展现。
系统方案
在当前鸿蒙next系统提供的文字排版方法基本没有合适使用的接口,包括imagespan和RichEditor,根据AI的回答,也只能harmony OS的旧语法
.textIndent(50.0)
.mode(textIndentMode.last_line)
实际该方法并不支持。
实现方案
思考一下关于这类型排版,基本只能依靠算法去变更展现内容,根据文字容器的宽度调整内容,添加文字尾部的空间和加上省略号,ImageSpan在这里就变成了一个可行的方案,缩减足够的文字通过span就能顺序展现图片,而且这种情况也能合理覆盖文字不满多行的情况。
代码实现
调整文本内容可以利用MeasureText from '@ohos.measure
@Monitor('content')
monitorContent() {
let sliceContent:string = this.content;
let flatContentWidth:number = px2vp(MeasureText.measureTextSize({textContent:sliceContent,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily}).width as number)
let containerWidth = this.containerWidth;
let leaveOutWidth = 30.0 + this.suffixSize.width;
let flatContainerWidth = containerWidth * this.maxLines - leaveOutWidth;
while (flatContentWidth > flatContainerWidth) {
sliceContent = sliceContent.slice(0,sliceContent.length-1);
flatContentWidth = px2vp(MeasureText.measureTextSize({textContent:sliceContent,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily}).width as number);
}
if (sliceContent.length < this.content.length) {
sliceContent = sliceContent + "..."
}
this.showText = sliceContent;
}
父组件需要传递容器尺寸限制
通过一个个字符去删除保证整个文本能完整的展现在容器内
多删除30vp是一个对省略号和图片间隔的大概估计
控件利用ImageSpan实现
Stack({ alignContent:Alignment.Bottom }) {
Text() {
Span(this.showText)
.fontSize(this.fontSize)
.fontWeight(this.fontWeight)
.fontFamily(this.fontFamily)
.lineHeight(this.lineHeight)
.fontColor(this.fontColor)
ImageSpan(this.suffix)
.width(this.suffixSize.width)
.height(this.suffixSize.height)
.objectFit(ImageFit.Contain)
.verticalAlign(ImageSpanAlignment.CENTER)
.margin({left:4.0})
}
}
.width('100%')
.height('100%')
使用span和imagespan的组合来保证图片紧贴文字之后
NZArticleTitleImageSuffixComponent({content:(data[index] as NZBannerBean).title,
fontSize:19.0,
fontWeight:500,
fontColor:$r('app.color.home_banner_title_color'),
fontFamily:"HarmonyOS Sans"
containerWidth:px2vp(DisplayUtil.getWidth())-54.0,
lineHeight:26.0,
maxLines:2.0,
suffix:$r('app.media.nanlogo_red'),
suffixSize:{width:20.0,height:20.0},
suffixAlign:ImageSpanAlignment.CENTER
调用方传递文字容器的大小限制,内容,字体相关属性,行数限制,后缀图片,大小限制,对齐方式。
实际效果