本示例通过自定义Span类型,在Text组件中使用ForEach遍历,根据不同的Span类型生成不同样式和功能的Span组件,实现部分文本高亮和超链接。
使用说明
export enum CustomSpanType {
Normal, // 普通文本,不含任何特殊格式或标记
Hashtag, // 话题标签
Mention, // @提及
VideoLink, // 视频链接
DetailLink // 正文详情
}
export class CustomSpan {
type: CustomSpanType; // 文本类型
content: string; // 文本内容
url?: string; // 跳转的链接地址
constructor(type: CustomSpanType = CustomSpanType.Normal, content: string, url?: string) {
this.type = type;
this.content = content;
if (url) {
this.url = url;
}
}
}
Text() {
ForEach(this.spans, (item: CustomSpan) => {
if (item.type === CustomSpanType.Normal) {
Span(item.content)
.fontSize($r('app.string.ohos_id_text_size_body1'))
} else if (item.type === CustomSpanType.Hashtag || item.type === CustomSpanType.Mention || item.type === CustomSpanType.DetailLink) {
TextLinkSpan({ item: item })
} else {
VideoLinkSpan({ item: item })
}
})
}
.width($r('app.string.styled_text_layout_100'))
.fontSize($r('app.string.ohos_id_text_size_body1'))
.margin({ top: $r('app.string.ohos_id_card_margin_start') })
Span(item.content)
.fontSize($r('app.string.ohos_id_text_size_body1'))
@Component
struct TextLinkSpan {
@State linkBackgroundColor: Color | Resource = Color.Transparent; // 超链接背景色
private item: CustomSpan = new CustomSpan(CustomSpanType.Normal, '');
@State myItem: CustomSpan = this.item;
aboutToAppear(): void {
// LazyForEach中Text组件嵌套自定义组件会有数据初次不渲染问题,异步修改状态变量更新视图
setTimeout(() => {
this.myItem = this.item;
})
}
build(){
Span(this.myItem.content)
.fontColor($r('app.color.styled_text_link_font_color'))// 超链接字体颜色
.fontSize($r('app.string.ohos_id_text_size_body1'))
.textBackgroundStyle({ color: this.linkBackgroundColor })
.onClick(() => {
this.linkBackgroundColor = $r('app.color.styled_text_link_clicked_background_color'); // 点击后的背景色
setTimeout(() => {
this.linkBackgroundColor = Color.Transparent;
}, BACKGROUND_CHANGE_DELAY)
// 根据文本超链接的类型做相应处理
if (this.myItem.type === CustomSpanType.Hashtag) {
promptAction.showToast({
message: $r('app.string.styled_text_hashtag_toast_message')
});
} else if (this.myItem.type === CustomSpanType.Mention) {
promptAction.showToast({
message: $r('app.string.styled_text_user_page_toast_message')
});
} else {
promptAction.showToast({
message: $r('app.string.styled_text_content_details_toast_message')
});
}
})
}
}
@Component
struct VideoLinkSpan {
@State linkBackgroundColor: Color | Resource = Color.Transparent;
private item: CustomSpan = new CustomSpan(CustomSpanType.Normal, '');
@State myItem: CustomSpan = this.item;
aboutToAppear(): void {
// LazyForEach中Text组件嵌套自定义组件会有数据初次不渲染问题,异步修改状态变量更新视图
setTimeout(() => {
this.myItem = this.item;
})
}
build() {
ContainerSpan() {
ImageSpan($r('app.media.styled_text_ic_public_video'))
.height($r('app.integer.styled_text_video_link_icon_height'))
.verticalAlign(ImageSpanAlignment.CENTER)
Span(this.myItem.content)
.fontColor($r('app.color.styled_text_link_font_color'))
.fontSize($r('app.string.ohos_id_text_size_body1'))
.onClick(() => {
this.linkBackgroundColor = $r('app.color.styled_text_link_clicked_background_color');
setTimeout(() => {
this.linkBackgroundColor = Color.Transparent;
}, BACKGROUND_CHANGE_DELAY)
promptAction.showToast({
message: $r('app.string.styled_text_video_function_message')
});
})
}
.textBackgroundStyle({ color: this.linkBackgroundColor })
}
}
本示例使用了LazyForEach进行数据懒加载
styledtext // har类型
|---/src/main/ets/mock
| |---MockData.ets // mock数据
|---/src/main/ets/model
| |---DataSource.ets // 列表数据模型
| |---TextModel.ets // 数据类型定义
|---/src/main/ets/pages
| |---StyledText.ets // 视图层-主页面
如果大家觉得这篇内容对学习鸿蒙开发有帮助,我想邀请大家帮我三个小忙:
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注小编,同时可以期待后续文章ing?,不定期分享原创知识。
更多鸿蒙最新技术知识点,请关注作者博客:鸿蒙实战经验分享:鸿蒙基础入门开发宝典! (qq.com)
更多回帖