HarmonyOS鸿蒙Next中属性字符串CustomSpan与同行字符串如何垂直居中对齐?
HarmonyOS鸿蒙Next中属性字符串CustomSpan与同行字符串如何垂直居中对齐?
demo如下,如何解决使用属性字符串的CustomSpan与同行字符串如何垂直居中对齐问题?
// xxx.ets
import { image } from '@kit.ImageKit'
import { LengthMetrics } from '@kit.ArkUI'
import { drawing, common2D } from '@kit.ArkGraphics2D'
import { MeasureText } from '@kit.ArkUI'
let gUIContext: UIContext;
class MyCustomSpan extends CustomSpan {
constructor(word: string) {
super();
this.word = word;
}
onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics {
let textSize = MeasureText.measureTextSize({ textContent: this.word, fontSize: measureInfo.fontSize })
this.width = textSize.width as number
this.height = textSize.height as number
console.info("test height: " + this.height)
return { width: px2vp(this.width) + this.paddingLeft * 2, height: px2vp(this.height) + this.paddingTop * 2 };
}
onDraw(context: DrawContext, options: CustomSpanDrawInfo) {
let canvas = context.canvas;
const brush = new drawing.Brush();
brush.setColor({
alpha: 255,
red: 0,
green: 0,
blue: 175
});
const font = new drawing.Font();
font.setSize(fp2px(30));
const textBlob = drawing.TextBlob.makeFromString(this.word, font, drawing.TextEncoding.TEXT_ENCODING_UTF8);
canvas.attachBrush(brush);
console.info("test : " + options.baseline + " : " + options.lineBottom)
let rect: common2D.Rect = {
left: options.x,
right: options.x + this.width + vp2px(this.paddingLeft * 2),
top: options.lineTop,
bottom: options.lineBottom
};
let roundRect = new drawing.RoundRect(rect, this.paddingTop, this.paddingTop); // 自定义 x/y 方向的半径
canvas.drawRoundRect(roundRect);
brush.setColor({
alpha: 255,
red: 23,
green: 169,
blue: 141
});
canvas.attachBrush(brush);
canvas.drawTextBlob(textBlob, options.x + vp2px(this.paddingLeft), options.baseline - vp2px(this.paddingTop));
canvas.detachBrush();
}
setWord(word: string) {
this.word = word;
}
width: number = 100;
word: string = "drawing";
height: number = 30;
paddingLeft: number = vp2px(8)
paddingTop: number = vp2px(8)
}
@Entry
@Component
struct AtSpan {
controller: TextController = new TextController();
imagePixelMap: image.PixelMap | undefined = undefined
customSpan1: MyCustomSpan = new MyCustomSpan("@小喵吃鱼");
async onPageShow() {
let customStyle = new MutableStyledString(this.customSpan1)
let message =
new StyledString('我是只可爱的小猫咪hhh,我每天需要吃很多好吃的,睡很多觉,这是我在论坛发布的探讨问题!')
customStyle.appendStyledString(message)
this.controller.setStyledString(customStyle)
}
build() {
Row() {
Column({ space: 5 }) {
Text(undefined, { controller: this.controller })
.copyOption(CopyOptions.InApp)
.draggable(true)
.fontSize(30)
.borderWidth(1)
}
.width('100%')
}
.height('100%')
}
}
运行效果:
;
private createCustomSpan(name: string) {
let fontSize = 30 // fp
let textSize = MeasureText.measureTextSize({ textContent: name, fontSize: fontSize })
let paddingLeft = vp2px(8)
let paddingTop = vp2px(8)
let width = (textSize.width as number) + paddingLeft * 2;
let height = (textSize.height as number) + paddingTop * 2;
const color: ArrayBuffer = new ArrayBuffer(width * height * 4); // 为需要创建的像素buffer大小,取值为:height * width *4
let opts: image.InitializationOptions = { pixelFormat: 3, size: { height: height, width: width } }
let pixelMap: image.PixelMap = image.createPixelMapSync(color, opts);
// 绘制背景
const canvas = new drawing.Canvas(pixelMap);
const brush = new drawing.Brush();
const color2: common2D.Color = {
alpha: 255,
red: 88,
green: 0,
blue: 0
};
brush.setColor(color2);
canvas.attachBrush(brush);
let rect: common2D.Rect = {
left: 0,
top: 0,
right: width,
bottom: height
};
let roundRect = new drawing.RoundRect(rect, paddingTop, paddingTop); // 自定义 x/y 方向的半径
canvas.drawRoundRect(roundRect);
canvas.detachBrush();
// 绘制文字
let myTextStyle: text.TextStyle = {
fontSize: vp2px(fontSize),
};
let myParagraphStyle: text.ParagraphStyle = {
textStyle: myTextStyle,
align: text.TextAlign.START,
};
let fontCollection = new text.FontCollection();
let paragraphGraphBuilder = new text.ParagraphBuilder(myParagraphStyle, fontCollection);
paragraphGraphBuilder.addText(name);
let paragraph = paragraphGraphBuilder.build();
paragraph.layoutSync(textSize.width as number);
paragraph.paint(canvas, paddingLeft, paddingTop);
// 创建ImageAttachment字符串
let customSpan = new MutableStyledString(new ImageAttachment({
value: pixelMap,
size: { width: px2vp(width), height: px2vp(height) },
layoutStyle: { margin: LengthMetrics.vp(2) }, // 行内margin
verticalAlign: ImageSpanAlignment.CENTER,
objectFit: ImageFit.None
}))
return customSpan
}
async onPageShow() {
let customSpan = this.createCustomSpan('@小喵吃鱼')
let message = new StyledString('我是只可爱的小猫咪hhh,我每天需要吃很多好吃的,睡很多觉,这是我在论坛发布的探讨问题!')
customSpan.appendStyledString(message)
this.controller.setStyledString(customSpan)
}
build() {
Row() {
Column({ space: 5 }) {
Text(undefined, { controller: this.controller })
.copyOption(CopyOptions.InApp)
.draggable(true)
.fontSize(30)
.borderWidth(1)
}
.width('100%')
}
.height('100%')
}
}
更多关于HarmonyOS鸿蒙Next中属性字符串CustomSpan与同行字符串如何垂直居中对齐?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,要使属性字符串CustomSpan与同行字符串垂直居中对齐,可以通过设置TextPaint
的baselineShift
属性来实现。具体步骤如下:
- 创建
CustomSpan
实例。 - 在
CustomSpan
的updateDrawState
方法中,通过TextPaint
的baselineShift
调整基线偏移量,使其与同行字符串对齐。 - 使用
SpannableString
将CustomSpan
应用到文本中。
示例代码:
CustomSpan customSpan = new CustomSpan() {
@Override
public void updateDrawState(TextPaint tp) {
tp.baselineShift = (int) (tp.ascent() / 2); // 调整基线偏移量
}
};
SpannableString spannableString = new SpannableString("Text with CustomSpan");
spannableString.setSpan(customSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
通过调整baselineShift
,可以实现CustomSpan
与同行字符串的垂直居中对齐。