玩溜Cocos Creator入门学习(三)UI系统介绍 UI的组件(Layout、EditBox、RichText)

Layout 组件

Layout 是一种容器组件,容器能够开启自动布局功能,自动按照规范排列所有子物体,方便用户制作列表、翻页等功能。

  • 水平布局容器
  • 垂直布局容器
  • 网格布局容器

选中你要添加组件的节点, 点击 属性检查器 下面的 添加组件 按钮,然后从 添加 UI 组件 中选择 Layout,即可添加 Layout 组件到节点上

Layout 属性

属性 功能说明
Type 布局类型,支持 NONE, HORIZONTAL,VERTICAL 和 GRID。
NONE 不会对子节点进行自动布局;
HORIZONTAL 横向自动排列子节点;
VERTICAL 垂直自动排列子节点;
GRID 采用网格方式对子节点进行自动布局;
ResizeMode 缩放模式,支持 NONE,CHILDREN 和 CONTAINER。
NONE 不会对子节点和容器进行大小缩放;
CHILDREN 对子节点的大小进行缩放
CONTAINER 对容器的大小进行缩放
PaddingLeft 排版时,子物体相对于容器左边框的距离。
PaddingRight 排版时,子物体相对于容器右边框的距离。
PaddingTop 排版时,子物体相对于容器上边框的距离。
PaddingBottom 排版时,子物体相对于容器下边框的距离。
SpacingX 水平排版时,子物体与子物体在水平方向上的间距。NONE 模式无此属性。
Horizontal Direction 指定水平排版时,第一个子节点从容器的左边还是右边开始布局。当容器为 Grid 类型时,此属性和 Start Axis 属性一起决定 Grid 布局元素的起始水平排列方向。
Vertical Direction 指定垂直排版时,第一个子节点从容器的上面还是下面开始布局。当容器为 Grid 类型时,此属性和 Start Axis 属性一起决定 Grid 布局元素的起始垂直排列方向。
Cell Size 此属性只在 Grid 布局时存在,指定网格容器里面排版元素的大小。
Start Axis 此属性只在 Grid 布局时存在,指定网格容器里面元素排版指定的起始方向轴。

详细说明

添加layout组件之后,默认的布局类型是NONE,它表示容器不会修改子物体的大小和位置,当用户手动摆放子物体时,容器会以容纳所有物体的最小矩形区域作为自身大小

通过修改 属性检查器 里面的Type可以切换布局容器的类型,可以切换水平、垂直或者网格布局。
另外,所有容器均支持(NONE容器只支持CONTAINER、NONE)。

  • 当ResizeMode 设置为NONE时,子物体和容器的大小变化互不影响。
  • 设置CHILDREN 则子物体大小会随着容器的大小而变化。
  • 设置CONTAINER 则容器的大小会随着子物体的大小而变化。

注意:

  1. Layout不会考虑子节点的缩放和旋转。
  2. Layout的设置后的结果需要到下一帧才会更新,除非你在设置完以后手动调用updateLayout

使用范例

例子一

Type ResizeMode Horizontal Direction
HORIZONTAL NONE LEFT_TO_RIGHT

在使用的过程中发现的特点:

  • 在我在父节点之中添加子节点的时候,每一个子节点都会按照 left to right 从左到右的排列顺序进行排序
  • 如果子节点不进行对齐挂件的操作,因为是水平布局,所以并没有在垂直坐标进行约束,这时候子节点可以随意的进行上下拖动,出现途中参差不齐
  • 一旦子节点添加超过了容器父节点的大小,那么就会出现图中截断现象
    • 解决方法就是:

      1.设置 ResizeMode 为 CHILDREN会对子节点进行大小缩放以变适应容器的大小来显示所有的子节点
      2.设置 ResizeMode 为 CONTAINER 对容器的大小进行缩放,这样容器就会有可能超过你设备的屏幕从而看不到所有的子节点,这样可以保证子节点不所以变化,容易会变大,这种形式一般用于滚动视图ScrollView

例子二

Type ResizeMode Horizontal Direction
HORIZONTAL CHILDREN LEFT_TO_RIGHT

这个例子就是为了验证在例子一种出现截断,以保持容器父节点不变的情况下,缩小子节点为代价的布局方案,这种方式的特点

  • 所有的子节点全部显示在父节点当中
  • 子节点会根据父节点的大小而改变自身的大小,父节点不会改变
  • 子节点大小,如果定义小的限制就需要设置子节点数量,子节点的数据直接关联子节点的大小

例子三

在一些特殊的场合,一个需求,水平布局的一组子节点(item),子节点(item)的大小是固定的,随着添加的子节点(item)的增加,设备的屏幕大小不够使用,子节点(item)出现断裂,超出屏幕,在这种情况下,我们通常会使用Scrollview、PageView这两种父节点(SuperView)。

ScrollView

  • 创建一个ScrollView的节点,删掉里面不必要的内容,只留下ScrollView、view,然后在这个节点当中设置它的属性块Contentcontent = view

  • 选中ScrollView设置它的属性:横向滚动、...等等你需要的设置,添加widget(对齐挂件)left、right、top、bottom = 0px 全屏适配

  • 在View(ScrollView的centent)添加widget(对齐挂件)、Layout(布局)并设置属性

    • 横向滚动、父节点(SuperView)根据子节点(SubView)的数量占用的大小拉伸父节点的宽度
    • 设置View的widget,left、top、bottom = 0px ,父节点变化的时候,不会改变x的大小(View在ScrollView中的初始位置),

View的属性设置

Type = HORIZONTAL  横向
Resize Model = CONTAINER  //父节点随子节点的数量拉伸
pading  all  = 10px       //所有边距为10
spacing x (子节点间隔) = 10px  //子节点的间隔为10
Horizontal Direction = left_to_right  //横向排列子节点时,总左向右

验证得到的结果是当我在View中创建多个子节点,超出屏幕的大小时,View会自动拉伸,View的父节点是ScrollView可以滚动

当然Layout还是会有很多的应用,在工作当中会经常用到这个UI组件,时间长了自然而然也就熟悉了

EditBox 组件

EditBox 是一个文本输入框,该组件能让你获取到用户输入的内容,就是输入文字、获取文字的地方。

EditBox 属性

属性 功能说明
String 输入框的初始输入内容,如果为空则会显示展位符的文本
Background image 输入框的背景图片
Keyboard Return Type 指定移动设备上面回车按钮的样式
Input Flag 指定输入标示:可以指定输入方式为密码或者单词首字母大写(仅支持Android)
Input Mode 指定输入模式:ANY表示多行输入,其他都是单行输入,移动平台上还可以指定键盘样式。
Font Size 输入框文本的字体大小
StayOnTop 输入总是可见,并且永远在游戏视图的上面
Tabindex 修改DOM输入元素的tabindex,这个属性只有在Web上面修改有意义。
Line Height 输入框文本的行高
Font Color 输入框文本的颜色
Placeholder 输入框占位符的文本内容
Placeholder Font Size 输入框占位符的字体大小
Placeholder Font Color 输入框占位符的字体颜色
Max Length 输入框最大允许输入的字符个数

查看属性检查器中的EditBox组件

EditBox 事件

事件 事件说明
Editing Did Began 当用户点击输入框,刚开始编辑的时候调用
Text Chnaged 当输入框中的数据的数据变化的时候调用
Editing Did Ended 在单行模式下面,一般是在用户按下回车或者点击屏幕输入框以外的地方调用该函数。 如果是多行输入,一般是在用户点击屏幕输入框以外的地方调用该函数。
Editing Return 输入回车的时候调用该函数如果是单行输入框失去编辑焦点,如果为移动端的时候则是点击Return按钮

Editing Did began 事件的定义

属性 功能说明
Target 带有脚本组件的节点
Component 脚本组件名称
Handler 指定一个回调函数,当用户开始输入文本的时候会调用该函数
CustomEventData 用户指定任意的字符串作为事件回调的最后一个参数传入

Text Changed 事件的定义

属性 功能说明
Target 带有脚本组件的节点
Component 脚本组件名称
Handler 指定一个回调函数,当用户正在输入文本的时候会调用该函数
CustomEventData 用户指定任意的字符串作为事件回调的最后一个参数传入

Editing Did Ended 事件的定义

属性 功能说明
Target 带有脚本组件的节点
Component 脚本组件名称
Handler 指定一个回调函数,当用户输入文本结束时会调用该函数
CustomEventData 用户指定任意的字符串作为事件回调的最后一个参数传入

Editing Return 事件的定义

属性 功能说明
Target 带有脚本组件的节点
Component 脚本组件名称
Handler 指定一个回调函数,当用户输入文本按下回车键时会调用该函数。
CustomEventData 用户指定任意的字符串作为事件回调的最后一个参数传入

EditBox 详细说明

  • Keyboard Return Type 特指在移动设备上面进行输入的时候,弹出的虚拟键盘上面的回车键样式
  • 如果需要输入密码,则需要把 Input Flag 设置为 password,同时 Input Mode 必须是 Any 之外的选择,一般选择 Single Line。
  • 如果要输入多行,可以把 Input Mode 设置为 Any。
  • 背景图片支持九宫格缩放

注意:如果在 iframe(嵌入式框架) 里面使用,最好把 stayOnTop 属性设置为 true
注解:iframe优缺点IFrame在网页中有什么作用

添加脚本、和使用脚本添加回调

第一种 通过属性检查器,编写脚本回调,两者结合的添加EditBox的回调

  • 在层级管理器当中创建一个EditBox, 名为EditBoxView

  • 资源管理器中添加一个EditBoxScript 脚本文件,并添加需要的回调函数

cc.Class({

    extends: cc.Component,
    properties: {
    },
    
    /*
     *  EditBox 文本输入框的回调函数
     **/
    onEditDidBegan: function(editbox, customEventData) {
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        // alert(customEventData);
        console.log(customEventData);
    },
    //假设这个回调是给 editingDidEnded 事件的
    onEditDidEnded: function(editbox, customEventData) {
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventData);
    },
    //假设这个回调是给 textChanged 事件的
    onTextChanged: function(text, editbox, customEventData) {
        //这里的 text 表示 修改完后的 EditBox 的文本内容
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventData);
    },
    //假设这个回调是给 editingReturn 事件的
    onEditingReturn: function(editbox,  customEventData) {
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventDat);
    },

});
  • EditBoxScript脚本文件添加到EditBoxView上面,属性检查器当中出现下面一项
  • 在属性检查器中的EditBox属性块中添加在EditBoxScript脚本中写好的方法

第二种 通过代码添加EditBox回调

这种方法添加的事件回调和使用编辑器添加的事件回调是一样的,通过代码添加, 你需要首先构造一个 cc.Component.EventHandler 对象,然后设置好对应的 target, component, handler 和 customEventData 参数。

  • 编写脚本文件EditBoxScript1
cc.Class({

    extends: cc.Component,

    properties: {

    },

    onLoad () {

        var editboxEventHandler = new cc.Component.EventHandler();
        editboxEventHandler.target = this.node; //这个 node 节点是你的事件处理代码组件所属的节点
        editboxEventHandler.component = "EditBoxScript1"
        editboxEventHandler.handler = "onEditDidBegan";
        editboxEventHandler.customEventData = "foobar";

        var editbox = this.node.getComponent(cc.EditBox);
        editbox.editingDidBegan.push(editboxEventHandler);
        // 你也可以通过类似的方式来注册其它回调函数
        //editbox.editingDidEnded.push(editboxEventHandler);
        //editbox.textChanged.push(editboxEventHandler);
        //editbox.editingReturn.push(editboxEventHandler);
    },

    onEditDidBegan: function(editbox, customEventData) {
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventData);
    },
    //假设这个回调是给 editingDidEnded 事件的
    onEditDidEnded: function(editbox, customEventData) {
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventData);
    },
    //假设这个回调是给 textChanged 事件的
    onTextChanged: function(text, editbox, customEventData) {
        //这里的 text 表示 修改完后的 EditBox 的文本内容
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventData);
    },
    //假设这个回调是给 editingReturn 事件的
    onEditingReturn: function(editbox,  customEventData) {
        //这里 editbox 是一个 cc.EditBox 对象
        //这里的 customEventData 参数就等于你之前设置的 "foobar"
        console.log(customEventData);
    },
});
  • 将该脚本拖入到目标UI组件YourEditBoxName属性检查器
**运行就可以拿到代码定义好的回调,以及代码中指定传输的值   以上**

第三种方式 通过 editbox.node.on('editing-did-began', ...) 的方式来添加

  • 编写脚本文件EditBoxScript2
cc.Class({
    extends: cc.Component,


    properties: {
    },

    onLoad: function () {
       var editbox = this.node.getComponent(cc.EditBox);
       editbox.node.on('editing-did-began', this.callback, this);
    },

    callback: function (event) {
       //这里的 event 是一个 EventCustom 对象,你可以通过 event.detail 获取 EditBox 组件
       //var editbox = event.detail;
       //do whatever you want with the editbox
       console.log(event.string);

    }
});

//同样的,你也可以注册 'editing-did-ended', 'text-changed' 和 'editing-return' 事件,这些事件的回调函数的参数与 'editing-did-began' 的参数一致。

  • 将该脚本拖入到目标UI组件YourEditBoxName属性检查器

官方文档的坑

官方文档其中写到的内容,event.detail,获取到的对象获取不到string,我在debug的时候调试看到event其实就是EditBox这个对象

callback: function (event) {
   //这里的 event 是一个 EventCustom 对象,你可以通过 event.detail 获取 EditBox 组件
   var editbox = event.detail;  //错误  
   //do whatever you want with the editbox
    
}

所以上述内容应该这么写

callback: function (event) {
   console.log(event.string);
}

以上是三种EditBox的回调事件的实现

RichText 组件

一个富文本组件
RichText 组件用来显示一段带有不同样式效果的文字,你可以通过一些简单的 BBCode 标签来设置文字的样式。 目前支持的样式有:颜色(color),字体大小(size),字体描边(outline),加粗(b),斜体(i),下划线(u),换行(br),图片(img)和点击事件(on),并且不同的 BBCode 标签是可以支持相互嵌套的。

BBCode 标签的内容,请参考本文档的 BBCode 标签格式说明

点击 属性检查器 下面的添加组件按钮,然后从添加渲染组件中选择 RichText,即可添加 RichText 组件到节点上。

富文本的脚本接口请参考 RichText API

RichText 属性

属性 功能说明
String 富文本的内容字符串,你可以在里面使用 BBCode来指定特定文本的样式
Horizonal Align 水平对齐方式
Font Size 字体大小,单位是point (注意,该字段不会影响BBCode里面设置的字体的大小)
Font 富文本定制字体,所有Label片段都会使用使用这个定制的TTF字体
Line Height 字体行高,单位是point
Max Width 富文本的最大宽度,传0的话意味着必须手动换行
Image Atlas 对于img标签里面的src属性名称,都需要在imageAtlas里面找到一个有效的spriteFrame,否则img tag会判断失效
Handle Touch Event 选中选项后,RichText将阻止节点边界框中的所有输入事件(鼠标,触摸),从而防止输入事件穿透到底层节点

BBCode 标签格式

目前支持的标签类型有:size,color, b, i, u, img 和 on,分别用来定制字体大小,字体颜色, 加粗,斜体,下划线,图片和点击事件。 每一个标签都有一个起始标签和一个结束标签,起始标签的名字和属性格式必要符合要求,且全部为小写。 结束标签的名字不做任何检查,只需要满足结束标签的定义即可。

下面分别是应用 size 和 color 标签的一个例子:

<color=green>你好</color>,<size=50>Mylove</>

支持标签

名称 描述 示例 注意事项
color 指定字体渲染颜色,颜色值可以是内置颜色,比如 white,black 等,也可以使用 16 进制颜色值,比如#ff0000 表示红色 <color=#ff0000>Red Text</color> 内置颜色值参考 cc.Color
size 指定字体渲染大小,大小值必须是一个整数 <size=30>enlarge me</size> Size 值必须使用等号赋值
outline 设置文本的描边颜色和描边宽度 <outline color=red width=4>A label with outline</outline> 如果你没有指定描边的颜色或者宽度的话,那么默认的颜色是白色(#ffffff),默认的宽度是 1
b 指定使用粗体来渲染 <b>This text will be rendered as bold</b> 名字必须是小写,且不能写成 bold
i 指定使用斜体来渲染 <i>This text will be rendered as italic</i> 名字必须是小写,且不能写成 italic
u 给文本添加下划线 <u>This text will have a underline</u> 名字必须是小写,且不能写成 underline
on 指定一个点击事件处理函数,当点击该 Tag 所在文本内容时,会调用该事件响应函数 <on click="handler"> click me! </on> 除了 on 标签可以添加 click 属性,color 和 size 标签也可以添加,比如 <size=10 click="handler2">click me</size>
br 插入一个空行
注意:
</br> 和
都是不支持的。
img 给富文本添加图文混排功能,img 的 src 属性必须是 ImageAtlas 图集里面的一个有效的 spriteframe 名称 < img src='ImageUrl' click='handler' /> 注意: 只有 < img src='ImageUrl' click='bar' /> 这种写法是有效的。如果你指定一张很大的图片,那么该图片创建出来的精灵会被等比缩放,缩放的值等于富文本的行高除以精灵的高度。

标签与标签是支持嵌套的,且嵌套规则跟 HTML 是一样的。比如下面的嵌套标签设置一个文本的渲染大小为 30,且颜色为绿色。

<size=30><color=green>I'm green</color></size>

也可以实现为:

<color=green><size=30>I'm green</size></color>

详细说明

富文本组件全部由 JS 层实现,采用底层的 Label 节点拼装而成,并且在上层做排版逻辑。 这意味着,你新建一个复杂的富文本,底层可能有十几个 label 节点,而这些 label 节点都是采用系统字体渲染的,

所以,一般情况下,你不应该在游戏的主循环里面频繁地修改富文本的文本内容, 这可能会导致性能比较低。

另外,如果能不使用富文本组件,就尽量使用普通的文本组件,并且 BMFont 的效率是最高的。

整理自:
cocos Creator官方文档

个人博客地址:

玩溜Cocos Creator入门学习(三)UI系统介绍 UI的组件(Layout、EditBox、RichText)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容