• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 图文混排
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @xiangyuan6-->
5<!--Designer: @pssea-->
6<!--Tester: @jiaoaozihao-->
7<!--Adviser: @HelloCrease-->
8
9图文混排是指图片与文字混合排列,文字可展示于图片四周。此排列方式能够直观呈现页面信息,增强视觉冲击力,使页面展示效果更加多样化。
10
11## 使用Span和ImageSpan实现图文混排
12
13通过Text组件设置[textVerticalAlign](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#textverticalalign20)属性和ImageSpan设置verticalAlign为ImageSpanAlignment.FOLLOW_PARAGRAPH,实现商品价格优惠信息展示的应用场景。
14
15```ts
16Text() {
17  ImageSpan($r('app.media.hot_sale'))
18    .width(50)
19    .height(30)
20    .borderRadius(5)
21    .verticalAlign(ImageSpanAlignment.FOLLOW_PARAGRAPH)
22  Span('惊喜价 ¥1299')
23    .fontSize(25)
24    .fontColor(Color.Red)
25  Span('1599')
26    .decoration({
27    type: TextDecorationType.LineThrough,
28    color: Color.Grey,
29    style: TextDecorationStyle.SOLID
30    })
31    .fontSize(16)
32}.textVerticalAlign(TextVerticalAlign.CENTER)
33```
34
35![span_imagespan_composition](figures/span_imagespan_composition.png)
36
37## 使用属性字符串实现图文混排
38
39通过[ImageAttachment](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#imageattachment)添加图片,[TextStyle](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#textstyle)设置多种文本样式,实现商品详情信息展示的应用场景。
40
41```ts
42// xxx.ets
43import { image } from '@kit.ImageKit';
44import { LengthMetrics } from '@kit.ArkUI';
45
46@Entry
47@Component
48struct styled_string_demo {
49  @State message: string = 'Hello World';
50  imagePixelMap: image.PixelMap | undefined = undefined;
51  @State imagePixelMap3: image.PixelMap | undefined = undefined;
52  mutableStr: MutableStyledString = new MutableStyledString('123');
53  controller: TextController = new TextController();
54  mutableStr2: MutableStyledString = new MutableStyledString('This is set decoration line style to the mutableStr2', [{
55    start: 0,
56    length: 15,
57    styledKey: StyledStringKey.DECORATION,
58    styledValue: new DecorationStyle({
59      type: TextDecorationType.Overline,
60      color: Color.Orange,
61      style: TextDecorationStyle.DOUBLE
62    })
63  }]);
64
65  async aboutToAppear() {
66    console.info("aboutToAppear initial imagePixelMap");
67    this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.sky'));
68  }
69
70  private async getPixmapFromMedia(resource: Resource) {
71    let unit8Array = await this.getUIContext().getHostContext()?.resourceManager?.getMediaContent(resource.id);
72    let imageSource = image.createImageSource(unit8Array?.buffer?.slice(0, unit8Array?.buffer?.byteLength));
73    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
74      desiredPixelFormat: image.PixelMapFormat.RGBA_8888
75    });
76    await imageSource.release();
77    return createPixelMap;
78  }
79
80  leadingMarginValue: ParagraphStyle = new ParagraphStyle({
81    leadingMargin: LengthMetrics.vp(5),
82    maxLines: 2,
83    overflow: TextOverflow.Ellipsis,
84    textVerticalAlign: TextVerticalAlign.BASELINE
85  });
86  //行高样式对象
87  lineHeightStyle1: LineHeightStyle = new LineHeightStyle(new LengthMetrics(24));
88  //Bold样式
89  boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold });
90  //创建含段落样式的对象paragraphStyledString1
91  paragraphStyledString1: MutableStyledString =
92    new MutableStyledString("\n高质量冲洗照片,高清冲印3/4/5/6寸包邮塑封,品质保证,", [
93      {
94        start: 0,
95        length: 28,
96        styledKey: StyledStringKey.PARAGRAPH_STYLE,
97        styledValue: this.leadingMarginValue
98      },
99      {
100        start: 11,
101        length: 4,
102        styledKey: StyledStringKey.LINE_HEIGHT,
103        styledValue: this.lineHeightStyle1
104      }
105    ]);
106  paragraphStyledString2: MutableStyledString = new MutableStyledString("\n限时直降5.15元 限量增送", [
107    {
108      start: 0,
109      length: 5,
110      styledKey: StyledStringKey.PARAGRAPH_STYLE,
111      styledValue: this.leadingMarginValue
112    },
113    {
114      start: 0,
115      length: 4,
116      styledKey: StyledStringKey.LINE_HEIGHT,
117      styledValue: new LineHeightStyle(new LengthMetrics(40))
118    },
119    {
120      start: 0,
121      length: 9,
122      styledKey: StyledStringKey.FONT,
123      styledValue: this.boldTextStyle
124    },
125    {
126      start: 1,
127      length: 9,
128      styledKey: StyledStringKey.FONT,
129      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(20), fontColor: Color.Red })
130    },
131    {
132      start: 11,
133      length: 4,
134      styledKey: StyledStringKey.FONT,
135      styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14) })
136    }
137  ]);
138  paragraphStyledString3: MutableStyledString = new MutableStyledString("\n¥22.50 销量400万+", [
139    {
140      start: 0,
141      length: 15,
142      styledKey: StyledStringKey.PARAGRAPH_STYLE,
143      styledValue: this.leadingMarginValue
144    },
145    {
146      start: 0,
147      length: 7,
148      styledKey: StyledStringKey.LINE_HEIGHT,
149      styledValue: new LineHeightStyle(new LengthMetrics(40))
150    },
151    {
152      start: 0,
153      length: 7,
154      styledKey: StyledStringKey.FONT,
155      styledValue: this.boldTextStyle
156    },
157    {
158      start: 1,
159      length: 1,
160      styledKey: StyledStringKey.FONT,
161      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18), fontColor: Color.Red })
162    },
163    {
164      start: 2,
165      length: 2,
166      styledKey: StyledStringKey.FONT,
167      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(36), fontColor: Color.Red })
168    },
169    {
170      start: 4,
171      length: 3,
172      styledKey: StyledStringKey.FONT,
173      styledValue: new TextStyle({ fontSize: LengthMetrics.vp(20), fontColor: Color.Red })
174    },
175    {
176      start: 7,
177      length: 9,
178      styledKey: StyledStringKey.FONT,
179      styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14) })
180    }
181  ]);
182
183  build() {
184    Row() {
185      Column({ space: 10 }) {
186        Text(undefined, { controller: this.controller })
187          .copyOption(CopyOptions.InApp)
188          .draggable(true)
189          .backgroundColor('#FFFFFF')
190          .borderRadius(5)
191          .width(210)
192
193        Button('点击查看商品详情')
194          .onClick(() => {
195            if (this.imagePixelMap !== undefined) {
196              this.mutableStr = new MutableStyledString(new ImageAttachment({
197                value: this.imagePixelMap,
198                size: { width: 210, height: 190 },
199                verticalAlign: ImageSpanAlignment.BASELINE,
200                objectFit: ImageFit.Fill,
201                layoutStyle: {
202                  borderRadius: LengthMetrics.vp(5)
203                }
204              }));
205              this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2);
206              this.paragraphStyledString1.appendStyledString(this.paragraphStyledString3);
207              this.mutableStr.appendStyledString(this.paragraphStyledString1);
208              this.controller.setStyledString(this.mutableStr);
209            }
210          })
211      }
212      .width('100%')
213    }
214    .height('100%')
215    .backgroundColor('#F8F8FF')
216  }
217}
218```
219
220![styledstring_composition](./figures/styledstring_composition.png)