zl程序教程

您现在的位置是:首页 >  其他

当前栏目

HarmonyOS 自定义View之图文标题

2023-03-15 22:42:21 时间

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

简介

日常项目中,我们可能会碰到一些标题加特效或多行内容+查看更多的需求,如果使用Text+Image这样去拼接的话,在复杂多“标签”场景就实现起来比较呆板,于是根据现有的HarmonyOS Text提供了一种思路实现了图文标题,我们需要在Text中进行图文混排。

效果演示

#星光计划1.0#HarmonyOS 自定义View之图文标题-鸿蒙HarmonyOS技术社区

TextImageTitle介绍

TextImageTitle是用来显示字符串+图片(或任意Component)的自定义控件,目前只支持头部或者尾部。

  1. private int textSize = 45; 
  2. private Color textColor = new Color(0xff000000); 
  3. private int lineHeight = 60; 
  4. private int maxTextLines = DEFAULT_LINES; 
  5. private int imageLayout; 
  6. private int imageResId; 
  7. private int imageWidth; 
  8. private int imageHeight; 
  9. private int imageMarginLeft; 
  10. private int imageMarginRight; 
  11. private Component imageComponent; 

TextImageTitle常用属性

TextImageTitle用法

在layout目录下的xml文件中创建TextImageTitle组件。

  1. <com.pvj.textimagetitlelibrary.TextImageTitle 
  2.     ohos:id="$+id:text0" 
  3.     ohos:height="match_content" 
  4.     ohos:width="match_parent" 
  5.     ohos:padding="10vp" 
  6.     /> 

1、设置图片在头部

示例代码:

  1. TextImageTitle textImageTitle = (TextImageTitle) findComponentById(ResourceTable.Id_text0); 
  2. TextImageTitle.Parameter parameter = new TextImageTitle.Parameter(). 
  3.         setMaxTextLines(1). 
  4.         setImageLayout(TextImageTitle.LAYOUT_FRONT). 
  5.         setImageResId(ResourceTable.Media_icon_notice). 
  6.         setLineHeight(80). 
  7.         setTextSize(50). 
  8.         setImageWidth(100).setImageHeight(80). 
  9.         setImageMarginRight(30). 
  10.         setImageMarginLeft(0); 
  11. textImageTitle.setParameter(parameter); 
  12. textImageTitle.setText("鸿蒙3.0有望在10月22日发布"); 

示例效果:

#星光计划1.0#HarmonyOS 自定义View之图文标题-鸿蒙HarmonyOS技术社区

2、设置Component在尾部

示例代码:

  1. TextImageTitle textImageTitle = (TextImageTitle) findComponentById(ResourceTable.Id_text1); 
  2. Component component = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_icon_tv2, textImageTitle, false); 
  3. TextImageTitle.Parameter parameter = new TextImageTitle.Parameter(). 
  4.         setMaxTextLines(1). 
  5.         setImageLayout(TextImageTitle.LAYOUT_TAIL). 
  6.         setImageComponent(component). 
  7.         setLineHeight(70). 
  8.         setTextSize(45). 
  9.         setImageWidth(400).setImageHeight(70). 
  10.         setImageMarginLeft(30); 
  11. textImageTitle.setParameter(parameter); 
  12. textImageTitle.setText("HarmonyOS 图文混排标题!"); 

示例效果:

 #星光计划1.0#HarmonyOS 自定义View之图文标题-鸿蒙HarmonyOS技术社区

3、设置多行文字尾部图片

示例代码:

  1. TextImageTitle textImageTitle = (TextImageTitle) findComponentById(ResourceTable.Id_text3); 
  2. TextImageTitle.Parameter parameter = new TextImageTitle.Parameter(). 
  3.         setMaxTextLines(3). 
  4.         setImageLayout(TextImageTitle.LAYOUT_TAIL). 
  5.         setImageResId(ResourceTable.Media_icon_more). 
  6.         setImageWidth(70).setImageHeight(70). 
  7.         setLineHeight(70). 
  8.         setTextSize(45). 
  9.         setImageMarginLeft(0). 
  10.         setImageMarginRight(50); 
  11. textImageTitle.setParameter(parameter); 
  12. textImageTitle.setText("华为开发者大会2021将在东莞松山湖举办,根据官方邀请函上透露出来的信息,鸿蒙HarmonyOS 3.0、HMS Core 6、全屋智能等黑科技也将悉数亮相鸿蒙HarmonyOS 2升级用户数量已经突破了1.3亿大关,并且华为鸿蒙OS系统目前平均每天升级用户数量都超过了100百万,根据华为目前的规划,鸿蒙OS系统的百机升级计划将会在今年12月份前后完成。"); 

示例效果:

#星光计划1.0#HarmonyOS 自定义View之图文标题-鸿蒙HarmonyOS技术社区

4、图片单击事件

  1. textImageTitle.setImageClickedListener(() -> { 
  2.     L.d("TextImageTitle""image click...."); 
  3.     // TODO do something.... 
  4. }); 

实现思路

根据遍历字符计算是否换行(细节请查看源代码)

  1. int titleLength = title.length(); 
  2. measurePaint.setTextSize(parameter.textSize); 
  3. int curLines = 1; 
  4. float curWidth = 0.0f; 
  5. int indexEnd = 0; 
  6.  
  7. //判断图文在前 还是在后 
  8. boolean isFront = parameter.imageLayout == LAYOUT_FRONT; 
  9.  // 1,遍历字符串 
  10. for (int index = 0; index < titleLength; index++) { 
  11.       String c = String.valueOf(title.charAt(index)); 
  12.       float vW = measurePaint.measureText(c); 
  13.       curWidth += vW; 
  14.      
  15.     //  一些行数 或每行宽度判断示例 头尾判断 
  16.     if (lineWidth < curWidth) { 
  17.         // ..... 省略大量代码 
  18.     } 
  19.      
  20.     if (lineWidth < curWidth + imageTotalWidth) { 
  21.        // ..... 省略大量代码 
  22.     } 
  23.      
  24.    if (isFront && curLines == 1) { 
  25.       // ..... 省略大量代码  
  26.    } 
  27.     ... 

绘制文字

  1. private void createText(String text) { 
  2.     // Text内容创建并且加到容器上 
  3.     Text titleText = new Text(getContext()); 
  4.     titleText.setTextSize(parameter.textSize); 
  5.     titleText.setTextColor(parameter.textColor); 
  6.     addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_PARENT, parameter.lineHeight); 
  7.     titleText.setText(text); 

 绘制图文

  1. private void createTextAndImage(String text, int maxTextWidth, boolean isFront) { 
  2.        //创建一个图片和文字的容器 
  3.        DirectionalLayout directionalLayout = new DirectionalLayout(getContext()); 
  4.        directionalLayout.setOrientation(ComponentContainer.HORIZONTAL); 
  5.        directionalLayout.setAlignment(LayoutAlignment.VERTICAL_CENTER); 
  6.        Text titleText = new Text(getContext()); 
  7.        titleText.setTextSize(parameter.textSize); 
  8.        titleText.setTextColor(parameter.textColor); 
  9.         // 文字的最大长度,决定尾部是否显示...;不限制有情况是Image出边界 
  10.        titleText.setMaxTextWidth(maxTextWidth); 
  11.        titleText.setMultipleLine(false); 
  12.        titleText.setTruncationMode(Text.TruncationMode.ELLIPSIS_AT_END); 
  13.        titleText.setText(text); 
  14.  
  15.        Component component = getImage(text); 
  16.        // 点击事件 
  17.        component.setClickedListener(new ClickedListener() { 
  18.            @Override 
  19.            public void onClick(Component component) { 
  20.                if (listener != null) { 
  21.                    listener.onClick(); 
  22.                } 
  23.            } 
  24.        }); 
  25.  
  26.        //判断图片在前还是在后 
  27.        if (isFront) { 
  28.            if (component != null) { 
  29.                directionalLayout.addComponent(component); 
  30.            } 
  31.            directionalLayout.addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_CONTENT,                                                           ComponentContainer.LayoutConfig.MATCH_PARENT); 
  32.        } else { 
  33.            directionalLayout.addComponent(titleText, ComponentContainer.LayoutConfig.MATCH_CONTENT,                                                           ComponentContainer.LayoutConfig.MATCH_PARENT); 
  34.            if (component != null) { 
  35.                directionalLayout.addComponent(component); 
  36.            } 
  37.        } 
  38.        addComponent(directionalLayout, ComponentContainer.LayoutConfig.MATCH_PARENT, parameter.lineHeight); 
  39.    } 
  40.  
  41.    private Component getImage(String text) { 
  42.         // 自定义Component优先 
  43.        if (parameter.imageComponent != null) { 
  44.            parameter.imageComponent.setComponentSize(parameter.imageWidth, parameter.imageHeight); 
  45.            parameter.imageComponent.setMarginLeft(parameter.imageMarginLeft); 
  46.            parameter.imageComponent.setMarginRight(parameter.imageMarginRight); 
  47.            return parameter.imageComponent; 
  48.        } else if (parameter.imageResId != 0) {   
  49.           //图文 
  50.            Image image = new Image(getContext()); 
  51.            image.setComponentSize(parameter.imageWidth, parameter.imageHeight); 
  52.            if (!TextTool.isNullOrEmpty(text)) { 
  53.                image.setMarginLeft(parameter.imageMarginLeft); 
  54.                image.setMarginRight(parameter.imageMarginRight); 
  55.            } 
  56.            image.setScaleMode(Image.ScaleMode.STRETCH); 
  57.            image.setPixelMap(parameter.imageResId); 
  58.            return image; 
  59.        } 
  60.        return null
  61.    } 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com