鸿蒙中 可变属性字符串MutableStyledString
本文介绍了ArkUI中的StyledString和MutableStyledString组件,它们支持精细化的文本样式控制,包括字符级和段落级样式设置。主要内容包括:1) 基本使用方法,推荐在onPageShow或onAppear回调中绑定;2) 6种样式类型(文本字体、阴影、装饰线等)的设置方法;3) 段落样式的创建和动态更新;4) 自定义样式CustomSpan的实现;5) 图文混排功能;6)
·
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、作用
-
StyledString:属性字符串,用于在字符或段落级别上设置文本样式
-
MutableStyledString:可变的属性字符串,继承自StyledString
-
功能:可以对文本进行精细化的样式控制,包括字体、颜色、大小、阴影、装饰线、行高、字符间距等
核心特性
-
支持字符级和段落级的样式设置
-
提供多种预定义样式对象
-
支持自定义样式(CustomSpan)
-
支持图文混排
-
支持事件绑定(点击、长按)
-
支持HTML格式转换
-
支持动态更新样式
二、使用
2.1 创建和绑定
@Entry
@Component
struct styled_string_demo1 {
// 创建StyledString
styledString1: StyledString = new StyledString("上课45分钟");
// 创建MutableStyledString
mutableStyledString1: MutableStyledString = new MutableStyledString("下课15分钟");
// 创建TextController
controller1: TextController = new TextController();
controller2: TextController = new TextController();
// 在onPageShow中绑定
async onPageShow() {
this.controller1.setStyledString(this.styledString1);
}
build() {
Column() {
// 显示属性字符串
Text(undefined, { controller: this.controller1 })
Text(undefined, { controller: this.controller2 })
.onAppear(() => {
// 在组件onAppear回调中绑定
this.controller2.setStyledString(this.mutableStyledString1);
})
}
.width('100%')
}
}
2.2 绑定时机
-
推荐在
onPageShow或onAppear回调中绑定 -
API version 15之前,在
aboutToAppear中绑定无法在页面初始化时显示 -
API version 15开始,
aboutToAppear中也可以正常显示
三、样式类型
3.1 文本字体样式(TextStyle)
import { LengthMetrics } from '@kit.ArkUI';
const textStyleAttrs: TextStyle = new TextStyle({
fontWeight: FontWeight.Bolder,
fontSize: LengthMetrics.vp(24),
fontStyle: FontStyle.Italic,
strokeWidth: LengthMetrics.px(5),
strokeColor: Color.Green,
fontColor: Color.Orange,
superscript: SuperscriptStyle.SUPERSCRIPT
});
3.2 文本阴影样式(TextShadowStyle)
const textShadowStyle = new TextShadowStyle({
radius: 5,
type: ShadowType.COLOR,
color: Color.Red,
offsetX: 10,
offsetY: 10
});
3.3 文本装饰线样式(DecorationStyle)
const decorationStyle = new DecorationStyle({
type: TextDecorationType.LineThrough, // 删除线
color: Color.Red,
thicknessScale: 3
});
// 支持多装饰线
const multiDecoration = new DecorationStyle(
{ type: TextDecorationType.Underline },
{ enableMultiType: true } // 开启多装饰线
);
3.4 基线偏移样式(BaselineOffsetStyle)
import { LengthMetrics } from '@kit.ArkUI';
const baselineOffsetStyle = new BaselineOffsetStyle(LengthMetrics.px(20));
3.5 行高样式(LineHeightStyle)
import { LengthMetrics } from '@kit.ArkUI';
const lineHeightStyle = new LineHeightStyle(LengthMetrics.vp(50));
3.6 字符间距样式(LetterSpacingStyle)
import { LengthMetrics, LengthUnit } from '@kit.ArkUI';
const letterSpacingStyle = new LetterSpacingStyle(
new LengthMetrics(20, LengthUnit.VP)
);
四、段落样式
4.1 段落分割
-
段落以换行符
\n结尾 -
ParagraphStyle可应用于段落开头、末尾或中间的任何位置
4.2 创建段落样式
import { LengthMetrics } from '@kit.ArkUI';
// 标题段落样式
const titleParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({
textAlign: TextAlign.Center
});
// 正文段落样式(首行缩进15vp)
const paragraphStyleAttr1: ParagraphStyle = new ParagraphStyle({
textIndent: LengthMetrics.vp(15)
});
// 创建带段落样式的属性字符串
const paragraphStyledString1: MutableStyledString = new MutableStyledString(
"段落标题\n正文第一段落开始0123456789正文第一段落结束。",
[
{
start: 0,
length: 4,
styledKey: StyledStringKey.PARAGRAPH_STYLE,
styledValue: titleParagraphStyleAttr
},
{
start: 5,
length: 20,
styledKey: StyledStringKey.LINE_HEIGHT,
styledValue: new LineHeightStyle(new LengthMetrics(24))
}
]
);
4.3 动态更新段落样式
// 创建新样式
const paragraphStyleAttr3: ParagraphStyle = new ParagraphStyle({
textAlign: TextAlign.End,
maxLines: 1,
wordBreak: WordBreak.BREAK_ALL,
overflow: TextOverflow.Ellipsis
});
// 替换样式
this.paragraphStyledString1.replaceStyle({
start: 5,
length: 3,
styledKey: StyledStringKey.PARAGRAPH_STYLE,
styledValue: paragraphStyleAttr3
});
// 更新显示
this.controller.setStyledString(this.paragraphStyledString1);
五、自定义样式(CustomSpan)
import { drawing } from '@kit.ArkGraphics2D';
class MyCustomSpan extends CustomSpan {
constructor(word: string, width: number, height: number, context: UIContext) {
super();
this.word = word;
this.width = width;
this.height = height;
this.context = context;
}
onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics {
return { width: this.width, height: this.height };
}
onDraw(context: DrawContext, options: CustomSpanDrawInfo) {
let canvas = context.canvas;
const brush = new drawing.Brush();
brush.setColor({ alpha: 255, red: 0, green: 74, blue: 175 });
const font = new drawing.Font();
font.setSize(25);
const textBlob = drawing.TextBlob.makeFromString(
this.word, font, drawing.TextEncoding.TEXT_ENCODING_UTF8
);
canvas.attachBrush(brush);
canvas.drawRect({
left: options.x + 10,
right: options.x + this.context.vp2px(this.width) - 10,
top: options.lineTop + 10,
bottom: options.lineBottom - 10
});
brush.setColor({ alpha: 255, red: 23, green: 169, blue: 141 });
canvas.attachBrush(brush);
canvas.drawTextBlob(textBlob, options.x + 20, options.lineBottom - 15);
canvas.detachBrush();
}
}
六、图文混排
6.1 添加图片(ImageAttachment)
import { image } from '@kit.ImageKit';
async aboutToAppear() {
// 获取图片资源
this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.sea'));
}
private async getPixmapFromMedia(resource: Resource) {
let unit8Array = await this.getUIContext().getHostContext()
?.resourceManager?.getMediaContent(resource.id);
let imageSource = image.createImageSource(
unit8Array?.buffer?.slice(0, unit8Array?.buffer?.byteLength)
);
let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
desiredPixelFormat: image.PixelMapFormat.RGBA_8888
});
await imageSource.release();
return createPixelMap;
}
// 创建带图片的属性字符串
this.mutableStr = new MutableStyledString(new ImageAttachment({
value: this.imagePixelMap,
size: { width: 180, height: 160 },
verticalAlign: ImageSpanAlignment.BASELINE,
objectFit: ImageFit.Fill
}));
七、事件处理
7.1 手势事件样式(GestureStyle)
const gestureStyleAttr: GestureStyle = new GestureStyle({
onClick: () => {
this.backgroundColor1 = Color.Green;
},
onLongPress: () => {
this.backgroundColor1 = Color.Grey;
}
});
// 设置样式
this.customSpanStyledString.setStyle({
start: 0,
length: 1,
styledKey: StyledStringKey.GESTURE,
styledValue: this.gestureStyleAttr
});
7.2 动态更新样式
// 通过setStyle接口叠加新样式或更新已有样式
this.customSpanStyledString.setStyle({
start: 0,
length: 1,
styledKey: StyledStringKey.GESTURE,
styledValue: this.gestureStyleAttr
});
// 需要主动触发更新
this.textController.setStyledString(this.customSpanStyledString);
八、HTML格式转换
8.1 转换为HTML(toHtml)
// 将属性字符串转换为HTML格式
this.html = StyledString.toHtml(this.styledString);
8.2 从HTML转换(fromHtml)
// 从HTML格式转换回属性字符串
let styledString = await StyledString.fromHtml(this.html);
this.controller2.setStyledString(styledString);
8.3 支持的HTML标签
-
<p>、<span>、<img>、<br> -
<strong>、<b>、<a>、<i>、<em> -
<s>、<u>、<del>、<sup>、<sub>
8.4 HTML转换
@State html: string = "<p>This is <b>b</b> <strong>strong</strong> ...</p>";
@State spanString: StyledString | undefined = undefined;
Button("Converted HTML to SpanString")
.onClick(async () => {
this.spanString = await StyledString.fromHtml(this.html);
this.controller.setStyledString(this.spanString);
})
Button("Converted SpanString to HTML")
.onClick(() => {
if (this.spanString) {
const newHtml = StyledString.toHtml(this.spanString);
this.html = newHtml;
}
})
更多推荐



所有评论(0)