效果图:
官方API:
@ohos.measure (文本计算)
- 方式一
measure.measureTextSize
跟方式二使用一样,只是API调用不同,可仔细查看官网
- 方式二
API 12+
import { display, promptAction } from '@kit.ArkUI'
import { MeasureUtils } from '@ohos.arkui.UIContext';
interface CustomTextSpanInterface {
isShow?: (isShow: boolean) => boolean;
}
@Component
export struct CustomTextSpan {
@State maxLines: number = 1
// 临时内容,用于计算
@State contentTemp: string = ''
// 折叠时 显示内容
@State showContent: string = ''
// 是否展开
@State isShow: boolean = false
@Prop fontSize: number
@Prop btnFontColor: number | string = Color.Blue
@Prop fontColor: number | string = '#000000'
// 原始内容
@Prop @Watch('getContent') content: string = ''
// 屏幕宽度 vp
@State w: number = -1
// vp
@Prop totalMargin: number = 0
@State measureUtils: MeasureUtils = this.getUIContext().getMeasureUtils();
@State computeHeight: SizeOptions = this.measureUtils.measureTextSize({
textContent: this.content
})
@State computeLine: SizeOptions = this.measureUtils.measureTextSize({
textContent: this.content
})
callback?: CustomTextSpanInterface
getContent() {
this.contentTemp = this.content
let temp = display.getDefaultDisplaySync().width
this.w = px2vp(temp) - this.totalMargin
this.computeHeight = this.measureUtils.measureTextSize({
textContent: this.content,
constraintWidth: this.w,
fontSize: this.fontSize
})
this.computeLine = this.measureUtils.measureTextSize({
textContent: this.content,
constraintWidth: this.w,
fontSize: this.fontSize,
maxLines: this.maxLines
})
this.compute()
}
compute() {
while (Number(this.computeHeight.height) > Number(this.computeLine.height)) {
// 通过循环,每次减少一个字符长度,重新计算,直到高度满足要求
this.contentTemp = this.contentTemp.substring(0, this.contentTemp.length - 1);
this.computeHeight = this.measureUtils.measureTextSize({
textContent: this.contentTemp + '...' + ' 展开', // <按钮文字>也要放入进行计算
constraintWidth: this.w,
fontSize: this.fontSize
});
this.showContent = this.contentTemp + '...'
}
}
build() {
Column() {
if (!this.isShow) {
Text() {
Span(`${this.showContent}`).fontColor(this.fontColor)
Span("展开").onClick(() => {
// 如果只是展开收起改变下值就行
// this.isShow = !this.isShow
// 真实项目,不需要展开而是需要一个弹窗 所以自定义回调 可以通过返回的boolean 控制 需要 展开还是弹窗
if (this.callback) {
this.isShow = this.callback?.isShow!(true)
}
}).fontColor(this.btnFontColor)
}.width('100%').fontSize(this.fontSize)
}
if (this.isShow) {
Text(this.content).width('100%').fontSize(this.fontSize).fontColor(this.fontColor)
Text("收起")
.width('100%')
.onClick(() => {
// this.isShow = !this.isShow
if (this.callback) {
this.isShow = this.callback?.isShow!(false)
}
})
.width('100%')
.textAlign(TextAlign.End)
.fontColor(this.btnFontColor)
.fontSize(this.fontSize)
}
}.width('100%')
}
}
使用:
CustomTextSpan({
content: `简介:${this.companyDetailEntiy.companyDesc}`,
fontSize: 12,
fontColor: "#000000",
btnFontColor: "#007FFF",
totalMargin: 28,// totalMargin= margin两边的距离 14+14
callback: {
isShow: (isShow: boolean) => {
// 不需要展开的话可做自己的业务
// return !isShow // 不需要展开
// 如果需要展开 return <isShow> 即可
return isShow
}
}
}).margin({ left: 14, right: 14 })