您现在的位置是:亿华云 > 系统运维

HarmonyOS 自定义View之图文标题

亿华云2025-10-03 01:30:30【系统运维】3人已围观

简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com简介日常项目中,我们可能会碰到一些标题加特效或多行内容+查看更多的需求,如果使用Text+

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

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

https://harmonyos.51cto.com

简介

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

效果演示

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文件中创建TextImageTitle组件。

<com.pvj.textimagetitlelibrary.TextImageTitle     ohos:id="$+id:text0"     ohos:height="match_content"     ohos:width="match_parent"     ohos:padding="10vp"     /> 

1、定义设置图片在头部

示例代码:

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日发布"); 

示例效果:

2、文标设置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 图文混排标题!"); 

示例效果:

 

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

示例代码:

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("华为开发者大会2021将在东莞松山湖举办,定义根据官方邀请函上透露出来的文标信息,鸿蒙HarmonyOS 3.0、HMS Core 6、全屋智能等黑科技也将悉数亮相鸿蒙HarmonyOS 2升级用户数量已经突破了1.3亿大关,并且华为鸿蒙OS系统目前平均每天升级用户数量都超过了100百万,根据华为目前的规划,鸿蒙OS系统的源码下载百机升级计划将会在今年12月份前后完成。"); 

示例效果:

4、图片单击事件

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

实现思路

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

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;     //  一些行数 或每行宽度判断示例 头尾判断     if (lineWidth < curWidth) {          // ..... 省略大量代码     }     if (lineWidth < curWidth + imageTotalWidth) {         // ..... 省略大量代码     }    if (isFront && curLines == 1) {        // ..... 省略大量代码     }     ... } 

绘制文字

private void createText(String text) {      // Text内容创建并且加到容器上     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) {         //创建一个图片和文字的容器        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);        // 点击事件        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优先        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;    } 

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

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

https://harmonyos.51cto.com

很赞哦!(28163)