HarmonyOS 自定義View之圖文標(biāo)題
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
簡介
日常項(xiàng)目中,我們可能會(huì)碰到一些標(biāo)題加特效或多行內(nèi)容+查看更多的需求,如果使用Text+Image這樣去拼接的話,在復(fù)雜多“標(biāo)簽”場景就實(shí)現(xiàn)起來比較呆板,于是根據(jù)現(xiàn)有的HarmonyOS Text提供了一種思路實(shí)現(xiàn)了圖文標(biāo)題,我們需要在Text中進(jìn)行圖文混排。
效果演示

TextImageTitle介紹
TextImageTitle是用來顯示字符串+圖片(或任意Component)的自定義控件,目前只支持頭部或者尾部。
- private int textSize = 45;
- private Color textColor = new Color(0xff000000);
- private int lineHeight = 60;
- private int maxTextLines = DEFAULT_LINES;
- private int imageLayout;
- private int imageResId;
- private int imageWidth;
- private int imageHeight;
- private int imageMarginLeft;
- private int imageMarginRight;
- private Component imageComponent;
TextImageTitle常用屬性
TextImageTitle用法
在layout目錄下的xml文件中創(chuàng)建TextImageTitle組件。
- <com.pvj.textimagetitlelibrary.TextImageTitle
- ohos:id="$+id:text0"
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:padding="10vp"
- />
1、設(shè)置圖片在頭部
示例代碼:
- TextImageTitle textImageTitle = (TextImageTitle) findComponentById(ResourceTable.Id_text0);
- TextImageTitle.Parameter parameter = new TextImageTitle.Parameter().
- setMaxTextLines(1).
- setImageLayout(TextImageTitle.LAYOUT_FRONT).
- setImageResId(ResourceTable.Media_icon_notice).
- setLineHeight(80).
- setTextSize(50).
- setImageWidth(100).setImageHeight(80).
- setImageMarginRight(30).
- setImageMarginLeft(0);
- textImageTitle.setParameter(parameter);
- textImageTitle.setText("鴻蒙3.0有望在10月22日發(fā)布");
示例效果:

2、設(shè)置Component在尾部
示例代碼:
- TextImageTitle textImageTitle = (TextImageTitle) findComponentById(ResourceTable.Id_text1);
- Component component = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_icon_tv2, textImageTitle, false);
- TextImageTitle.Parameter parameter = new TextImageTitle.Parameter().
- setMaxTextLines(1).
- setImageLayout(TextImageTitle.LAYOUT_TAIL).
- setImageComponent(component).
- setLineHeight(70).
- setTextSize(45).
- setImageWidth(400).setImageHeight(70).
- setImageMarginLeft(30);
- textImageTitle.setParameter(parameter);
- textImageTitle.setText("HarmonyOS 圖文混排標(biāo)題!");
示例效果:
3、設(shè)置多行文字尾部圖片
示例代碼:
- TextImageTitle textImageTitle = (TextImageTitle) findComponentById(ResourceTable.Id_text3);
- TextImageTitle.Parameter parameter = new TextImageTitle.Parameter().
- setMaxTextLines(3).
- setImageLayout(TextImageTitle.LAYOUT_TAIL).
- setImageResId(ResourceTable.Media_icon_more).
- setImageWidth(70).setImageHeight(70).
- setLineHeight(70).
- setTextSize(45).
- setImageMarginLeft(0).
- setImageMarginRight(50);
- textImageTitle.setParameter(parameter);
- textImageTitle.setText("華為開發(fā)者大會(huì)2021將在東莞松山湖舉辦,根據(jù)官方邀請函上透露出來的信息,鴻蒙HarmonyOS 3.0、HMS Core 6、全屋智能等黑科技也將悉數(shù)亮相鴻蒙HarmonyOS 2升級(jí)用戶數(shù)量已經(jīng)突破了1.3億大關(guān),并且華為鴻蒙OS系統(tǒng)目前平均每天升級(jí)用戶數(shù)量都超過了100百萬,根據(jù)華為目前的規(guī)劃,鴻蒙OS系統(tǒng)的百機(jī)升級(jí)計(jì)劃將會(huì)在今年12月份前后完成。");
示例效果:

4、圖片單擊事件
- textImageTitle.setImageClickedListener(() -> {
- L.d("TextImageTitle", "image click....");
- // TODO do something....
- });
實(shí)現(xiàn)思路
根據(jù)遍歷字符計(jì)算是否換行(細(xì)節(jié)請查看源代碼)
- int titleLength = title.length();
- measurePaint.setTextSize(parameter.textSize);
- int curLines = 1;
- float curWidth = 0.0f;
- int indexEnd = 0;
- //判斷圖文在前 還是在后
- boolean isFront = parameter.imageLayout == LAYOUT_FRONT;
- // 1,遍歷字符串
- for (int index = 0; index < titleLength; index++) {
- String c = String.valueOf(title.charAt(index));
- float vW = measurePaint.measureText(c);
- curWidth += vW;
- // 一些行數(shù) 或每行寬度判斷示例 頭尾判斷
- if (lineWidth < curWidth) {
- // ..... 省略大量代碼
- }
- if (lineWidth < curWidth + imageTotalWidth) {
- // ..... 省略大量代碼
- }
- if (isFront && curLines == 1) {
- // ..... 省略大量代碼
- }
- ...
- }
繪制文字
- private void createText(String text) {
- // Text內(nèi)容創(chuàng)建并且加到容器上
- Text titleText = new Text(getContext());
- titleText.setTextSize(parameter.textSize);
- titleText.setTextColor(parameter.textColor);
- addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_PARENT, parameter.lineHeight);
- titleText.setText(text);
繪制圖文
- private void createTextAndImage(String text, int maxTextWidth, boolean isFront) {
- //創(chuàng)建一個(gè)圖片和文字的容器
- DirectionalLayout directionalLayout = new DirectionalLayout(getContext());
- directionalLayout.setOrientation(ComponentContainer.HORIZONTAL);
- directionalLayout.setAlignment(LayoutAlignment.VERTICAL_CENTER);
- Text titleText = new Text(getContext());
- titleText.setTextSize(parameter.textSize);
- titleText.setTextColor(parameter.textColor);
- // 文字的最大長度,決定尾部是否顯示...;不限制有情況是Image出邊界
- titleText.setMaxTextWidth(maxTextWidth);
- titleText.setMultipleLine(false);
- titleText.setTruncationMode(Text.TruncationMode.ELLIPSIS_AT_END);
- titleText.setText(text);
- Component component = getImage(text);
- // 點(diǎn)擊事件
- component.setClickedListener(new ClickedListener() {
- @Override
- public void onClick(Component component) {
- if (listener != null) {
- listener.onClick();
- }
- }
- });
- //判斷圖片在前還是在后
- if (isFront) {
- if (component != null) {
- directionalLayout.addComponent(component);
- }
- directionalLayout.addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
- } else {
- directionalLayout.addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
- if (component != null) {
- directionalLayout.addComponent(component);
- }
- }
- addComponent(directionalLayout, ComponentContainer.LayoutConfig.MATCH_PARENT, parameter.lineHeight);
- }
- private Component getImage(String text) {
- // 自定義Component優(yōu)先
- if (parameter.imageComponent != null) {
- parameter.imageComponent.setComponentSize(parameter.imageWidth, parameter.imageHeight);
- parameter.imageComponent.setMarginLeft(parameter.imageMarginLeft);
- parameter.imageComponent.setMarginRight(parameter.imageMarginRight);
- return parameter.imageComponent;
- } else if (parameter.imageResId != 0) {
- //圖文
- Image image = new Image(getContext());
- image.setComponentSize(parameter.imageWidth, parameter.imageHeight);
- if (!TextTool.isNullOrEmpty(text)) {
- image.setMarginLeft(parameter.imageMarginLeft);
- image.setMarginRight(parameter.imageMarginRight);
- }
- image.setScaleMode(Image.ScaleMode.STRETCH);
- image.setPixelMap(parameter.imageResId);
- return image;
- }
- return null;
- }
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)