#2020征文-TV#「续3.1.1 文本组件」不需要背景图,自定义绘制会 原创 精华

Tuer白晓明
发布于 2020-12-7 17:30
浏览
7收藏

上节我们对Text组件有了详细的认知,我们可以通过设置Text组件的各类属性来让Text组件美观起来,但是我们仅仅能设置背景、字体大小、字体大小自适应、内容折行、外边距、内边距等。很多时候我们想给字体设置边框、圆角、阴影等等特殊的效果,但是在属性中没有特定的属性可以完成这件事。当然我们可以给Text组件设置背景图片,这样也可以达到我们的预期效果,但是如果整个APP中图片比较多会增加我们安装包的体积,还会在各种手机的适配上出现不可预知的问题。

 

官方团队提供了一个可以绘制带有颜色、渐变、边框,用于视图背景的,及设置各种形状的类—ShapeElement

 

ShapeElement类源码

ShapeElement类是Element的子类,Element类有多个扩展类,这里就不详细说明了,后面我们在需要的时候再扩展讲解。目前Java API中提供了多个常量值,两个构造函数,以及多个绘图方法。

 

我们先来了解一下能够设置哪些形状?

ShapeElement类提供了设置矩形、椭圆形、直线、圆弧和路径(以直线段、二次曲线和三次曲线的几何组合表示多轮廓路径)。本节仅对前三个几何图形做介绍,后两个后面小节会详细介绍。

/**
  * 继承自Element,提供了带有颜色渐变的可绘制实例,通常用于视图背景
  */
public class ShapeElement extends Element {
    // 可绘制的几何图形
    // 绘制形状为矩形
    public static final int RECTANGLE = 0;
    // 绘制形状为椭圆
    public static final int OVAL = 1;
    // 绘制形状为直线
    public static final int LINE = 2;
    
    //默认构造器,在代码中设定几何图形和背景的话,使用这个构造函数
    public ShapeElement() {}
    //引用资源文件中设定的几何图形和背景的话,使用这个构造函数
    //xmlId为资源文件的内存地址
    public ShapeElement(Context context, int xmlId) {}
    
    //设置要显示的集合图形,参数为上面的静态常量
    public void setShape(int shape) {}
    //设置背景颜色
    public void setRgbColor(RgbColor color) {}
    //设置渐变效果填充的颜色值,参数为颜色数组,对直线无效
    public void setRgbColors(RgbColor[] colors) {}
    //设置边框的宽度和颜色
    public void setStroke(int width, RgbColor color) {}
    //设置圆角半径,这个方法仅对矩形有效
    public void setCornerRadius(float radius) {}
    //设置每个角的半径,这个方法仅对矩形有效
    //表示四个角的半径数组。如果数组的长度不等于8,则该设置无效。
    // 每对半径表示一个角的x轴半径和y轴半径。
    public void setCornerRadiiArray(float[] radii) {}
    //指定组件的渐变效果方向
    public void setOrientation(ShapeElement.Orientation orientation) {}
    public void setGradientOrientation(ShapeElement.Orientation orientation) {}
    //设置虚线的间隔和相位
    //数组项是成对的:这些值的偶数和奇数索引分别指定要绘制的象素个数和空白象素个数。
    public void setDashPathEffectValues(float[] intervals, float phase) {}
}

ShapeElement实例应用

上面我们将常用的源码做了简单分析,接下来我们将以实操为主,能够熟练掌握ShapeElement的应用。

#2020征文-TV#「续3.1.1 文本组件」不需要背景图,自定义绘制会-鸿蒙开发者社区

我们先来看看上面的UI界面,上面有三种自定义文本显示,矩形、椭圆形、直线。而OHOS还提供了圆弧和基于路径的多形状图。在矩形中,我们分别实现了默认的矩形背景,四角相同的圆角矩形背景,四角不同的圆角矩形背景,实线边框的矩形背景,虚线边框的矩形背景,椭圆背景,圆形背景,及直线背景。

 

首先我们先了解一下,我们为何使用这种类型的背景。

1、给app瘦身,可以替代纯色和渐变色的组件背景

2、编写一个矩形、圆、椭圆,便于维护,只需要改动少量代码即可实现效果

3、节省内存
这些设置背景的图形和背景色在ShapeElement类中,ShapeElement类是Element类的子类,该类用于实现带有渐变效果的图形化视图背景。其提供了矩形、椭圆形、直线、圆弧和基于路径的多形状图,本节我们先来对矩形、椭圆形和直线做示例介绍,后两种我们在后续开专门的小节做详细介绍。


矩形

矩形是常见的视图背景,我们可以设置默认的矩形、带圆角的矩形、带边框的矩形。

//矩形背景
DirectionalLayout rectangle_layout = initChildDirectionalLayout(this);

//这个组件显示的效果是"带背景的矩形"
Text rectangle_background_text = initText(this, "带背景的矩形");
//设置背景色
ShapeElement rectangle_background_text_element = initChildShapeElement(this);
rectangle_background_text_element.setShape(ShapeElement.RECTANGLE);
rectangle_background_text.setBackground(rectangle_background_text_element);
rectangle_layout.addComponent(rectangle_background_text);

//这个组件显示的效果是"带背景和圆角的矩形"
Text rectangle_background_radius_text = initText(this, "带背景和圆角的矩形");
//设置背景色和圆角
ShapeElement rectangle_background_radius_text_element = initChildShapeElement(this);
rectangle_background_radius_text_element.setShape(ShapeElement.RECTANGLE);
rectangle_background_radius_text_element.setCornerRadius(20);
rectangle_background_radius_text_element.setDashPathEffectValues(new float[]{20f, 25f, 30f, 35f}, 2);
rectangle_background_radius_text.setBackground(rectangle_background_radius_text_element);
rectangle_layout.addComponent(rectangle_background_radius_text);

//这个组件显示的效果是"带背景和四角不同圆角的矩形"
Text rectangle_background_different_radius_text = initText(this, "带背景和不同圆角的矩形");
//设置背景色和每个角的圆角
ShapeElement rectangle_background_different_radius_text_element = initChildShapeElement(this);
rectangle_background_different_radius_text_element.setShape(ShapeElement.RECTANGLE);
rectangle_background_different_radius_text_element.setCornerRadiiArray(new float[]{20, 40, 30, 60, 20, 20, 100, 120});
rectangle_background_different_radius_text.setBackground(rectangle_background_different_radius_text_element);
rectangle_layout.addComponent(rectangle_background_different_radius_text);


//这个组件显示的效果是"渐变背景"矩形
Text gradient_background_text = initText(this, "带渐变效果的矩形背景");
//设置背景色和渐变(从下端角到上端角)
ShapeElement gradient_background_text_element = initChildShapeElement(this);
gradient_background_text_element.setShape(ShapeElement.RECTANGLE);
RgbColor[] rgbColors = new RgbColor[]{new RgbColor(34, 197, 255), new RgbColor(255, 197, 34)};
gradient_background_text_element.setRgbColors(rgbColors);
gradient_background_text_element.setGradientOrientation(ShapeElement.Orientation.BOTTOM_END_TO_TOP_START);
gradient_background_text.setBackground(gradient_background_text_element);
rectangle_layout.addComponent(gradient_background_text);

//这个组件的效果是"实线边框的背景"矩形
Text stroke_background_text = initText(this, "实线边框的背景");
//设置背景色和路径
ShapeElement stroke_background_text_element = initChildShapeElement(this);
stroke_background_text_element.setShape(ShapeElement.RECTANGLE);
stroke_background_text_element.setStroke(5, new RgbColor(255, 197, 34));
stroke_background_text.setBackground(stroke_background_text_element);
rectangle_layout.addComponent(stroke_background_text);

//这个组件的效果是"虚线边框的背景"矩形
Text stroke_dash_background_text = initText(this, "虚线边框的背景");
//设置背景色和路径
ShapeElement stroke_dash_background_text_element = initChildShapeElement(this);
stroke_dash_background_text_element.setShape(ShapeElement.RECTANGLE);
stroke_dash_background_text_element.setStroke(5, new RgbColor(255, 197, 34));
stroke_dash_background_text_element.setDashPathEffectValues(new float[]{10, 21, 32, 43, 54, 65}, 1);
stroke_dash_background_text.setBackground(stroke_dash_background_text_element);
rectangle_layout.addComponent(stroke_dash_background_text);

#2020征文-TV#「续3.1.1 文本组件」不需要背景图,自定义绘制会-鸿蒙开发者社区OHOS也提供了加载XML资源文件的方法,在graphic文件夹下可以创建xml类型的可绘制资源,如SVG可缩放矢量图形文件、基本的几何图形(如矩形、圆形、线等)shape资源,下面是shape资源XML格式:

<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:shape="rectangle">
    <solid
        ohos:color="#FFFFFF"/>
</shape>

其中ohos:shape是指定几何图形,rectangle为矩形样式。shape的属性有solid(背景色)、corners表示圆角、gradient表示渐变、stroke表示边框。

<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:shape="rectangle">
    <solid
        ohos:color="#FF6A5C"/>

    <corners
        ohos:radius="20"/>
<!-- 由于缺少相关文档,还未摸索出渐变的设置方式 -->
<!--    <gradient/>-->

    <stroke
        ohos:width="2"
        ohos:color="#000000"/>
</shape>

#2020征文-TV#「续3.1.1 文本组件」不需要背景图,自定义绘制会-鸿蒙开发者社区

椭圆形

椭圆一般我们不常用,但是圆形我们是常用的,比如默认头像,我们使用纯色背景来实现。

//椭圆形背景
DirectionalLayout oval_layout = initChildDirectionalLayout(this);

//这个组件显示的效果是"带背景的椭圆"
Text oval_background_text = initText(this, "带背景的椭圆");
//设置背景和椭圆
ShapeElement oval_background_text_element = initChildShapeElement(this);
oval_background_text_element.setShape(OVAL);
oval_background_text.setBackground(oval_background_text_element);
oval_layout.addComponent(oval_background_text);

//这个组件显示的效果是"带背景的圆"
Text circular_background_text = initText(this, "带背景的圆");
circular_background_text.setWidth(300);
circular_background_text.setHeight(300);
circular_background_text.setTextAlignment(CENTER);
//设置背景和圆(组件的宽高一样的时候是圆)
ShapeElement circular_background_text_element = initChildShapeElement(this);
circular_background_text_element.setShape(OVAL);
circular_background_text.setBackground(circular_background_text_element);
oval_layout.addComponent(circular_background_text);
layout.addComponent(oval_layout);

#2020征文-TV#「续3.1.1 文本组件」不需要背景图,自定义绘制会-鸿蒙开发者社区

直线

直线我们只需要了解即可,这个实际项目中没有多大意义。

//直线
DirectionalLayout line_layout = initChildDirectionalLayout(this);

Text line_background_text = initText(this, "直线");
ShapeElement line_background_text_element = initChildShapeElement(this);
line_background_text_element.setShape(LINE);
line_background_text.setBackground(line_background_text_element);
line_layout.addComponent(line_background_text);
layout.addComponent(line_layout);

#2020征文-TV#「续3.1.1 文本组件」不需要背景图,自定义绘制会-鸿蒙开发者社区

本小节我们对ShapeElement类有了一些具体的了解,在后面的组件中将不在详细介绍,可以根据本节内容自定义不同样式的组件。对于ShapeElement类中的另外两个绘制几何图形的方法,我将在后面的小节中单独介绍。

XML文件方式设置我在文中简单的做了介绍,如果直接在布局XML中引用graphic文件下的资源,可以设置组件的ohos:background_element属性。

ohos:background_element="$graphic:rectangle_background_radius_text"

 

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
自定义组件样式.zip 1.19M 89次下载
已于2020-12-12 08:35:55修改
7
收藏 7
回复
举报
9条回复
按时间正序
/
按时间倒序
Tuer白晓明
Tuer白晓明

    下篇内容预告:      

            Image组件源码

            Image实例应用

            Image组件和Text组件组合实例

回复
2020-12-7 17:41:53
红叶亦知秋
红叶亦知秋

厉害了,老师写文章是真的效率。

1
回复
2020-12-7 18:56:27
wx59c0ce7573175
wx59c0ce7573175

如果要动态设置背景图片怎么设置。目前只会在xml里设置ohos:background_element才能引用资源文件,动态设置不知道方法。

回复
2021-1-22 10:00:43
Tuer白晓明
Tuer白晓明 回复了 wx59c0ce7573175
如果要动态设置背景图片怎么设置。目前只会在xml里设置ohos:background_element才能引用资源文件,动态设置不知道方法。

你可以先预定义多个xml背景图片样式,然后在Java中使用下面方式进行动态引入

ShapeElement shapeElement = new ShapeElement(getContext(), ResourceTable.Graphic_background_ability_main);
回复
2021-1-22 11:44:52
wx59c0ce7573175
wx59c0ce7573175 回复了 Tuer白晓明
你可以先预定义多个xml背景图片样式,然后在Java中使用下面方式进行动态引入 ShapeElement shapeElement = new ShapeElement(getContext(), ResourceTable.Graphic_background_ability_main);

这个只能引用Graphic,media会报错呀

已于2021-1-22 14:02:01修改
回复
2021-1-22 13:37:57
张荣超_九丘教育
张荣超_九丘教育

期待类似基础组件详细分享的持续更新~~666~~

回复
2021-1-31 01:20:37
麒麟Berlin
麒麟Berlin 回复了 wx59c0ce7573175
这个只能引用Graphic,media会报错呀

media用PixelMapElement

回复
2021-3-22 17:48:14
甜甜爱开发
甜甜爱开发

老师好,shape阴影在鸿蒙开发中怎么写呢?期待回复,谢谢

回复
2021-9-16 15:33:57
Tuer白晓明
Tuer白晓明 回复了 甜甜爱开发
老师好,shape阴影在鸿蒙开发中怎么写呢?期待回复,谢谢

使用JS开发的话可以通过设置CSS样式来控制。

如果使用Java开发,可以通过drawToCanvas方法绘制一个。

回复
2021-9-16 17:26:29
回复
    相关推荐