首页 > 代码库 > EUI库 - 皮肤

EUI库 - 皮肤

 

皮肤分离机制
   皮肤分离机制对制作可复用的外观比较有优势
那对于只使用一次的皮肤呢?如果也拆分出两个文件,显然不太方便。这里我们针对单次使用的皮肤定制了内部类的功能
  每个组件都有一个childrenCreated()方法,它会在组件初始化完成后回调,子类通常覆盖这个方法来访问一些延迟实例化的子项。
皮肤部件 在皮肤附加到逻辑组件上时,会自动匹配双方的同名变量和id,这些同名变量就叫做“皮肤部件”(SkinPart)
  。当为某个组件定制皮肤时,实际上就分为创建对应的皮肤部件和显示图片素材两部分。如果只添加了图片素材,而没有声明并实例化对应变量名的皮肤部件,逻辑组件将无法正常工作
  所有的可定制皮肤组件都必须继承自eui.Component或它的子类
视图状态
可以看出自定义逻辑组件中扩展视图状态的方法就是使用invalidateState()和getCurrentState()这一对方法 
http://developer.egret.com/cn/github/egret-docs/extension/EUI/skin/state/index.html
  我们还提供了一种在组件外快速设置视图状态的方法。就是直接对组件的currentState属性赋值即可,例如:button.currentState = "down";
配置主题
default.thm.json
{
"skins": {
    "eui.Button": "skins/ButtonSkin.exml"
},
"exmls": [ ],
"autoGenerateExmlsList": true //设为true后,会自动在exmls里生成EXML文件信息
}
 
skins 指定组件的默认皮肤,其中键是组件的类名,值是你需要赋值给这个组件skinName属性的值,可以是exml文件路径,也可以是Exml文件上注册的类名
exmls  表示需要主题预加载的 EXML 文件列表。Theme 文件加载之后,它会优先加载这个列表中的EXML文件,由于 EXML 可能会存在相互依赖,所以 Theme
按照列表中的顺序编译 EXML。你可以监听 egret.Event.COMPLETE 来确认该列表中的EXML已经加载完成
 
autoGenerateExmlsList 表示是否需要使用命令行工具自动生成 EXML 列表。build 命令会查找项目中的 EXML 文件,
并根据 EXML 文件的依赖关系自动排序后,放到这个列表中。在项目发布时,命令行工具会将 EXML 文件的内容直接集成到 theme 文件中,
减少网络请求的次数(参考下面的示例)。如果您想要自定义 EXML 列表,请将值设置为 false
 
设置版本号:防止缓存
"exmls": [
"resource/eui_skins/ButtonSkin.exml?v=20151211"
]
启用主题
public constructor(){
this.once(egret.Event.ADDED_TO_STAGE,this.onAddedToStage,this);
}
public onAddedToStage(event:egret.Event):void{
new eui.Theme("resource/default.thm.json", this.stage);
}
 
创建了Theme之后,它会开始异步加载指定的主题文件并解析,在加载的过程中,如果已经有组件在创建,也不需要额外处理,这部分组件在主题加载完成后会自动重新查询一次默认皮肤
 
特别注意一下,主题配置文件只是起到设置默认值的作用,并不能运行时切换所有默认皮肤。因为这么做需要遍历整个显示列表,开销比较大。
使用自定义的皮肤 方式一
加载文件
class TestSkin extends eui.Component {
constructor() {
super();
this.addEventListener(eui.UIEvent.COMPLETE,this.onComplete,this);
this.skinName = "resource/testSkin.exml";// 还可以写成 this.skinName = “mySkin.TestSkin”
}
protected createChildren() {
super.createChildren();
console.log("createChildren")
}
private onComplete():void{
console.log("onComplete");
          }
}
直接把skinName设置为exml文件的路径。这种方式要注意的是,在 createChildren 的时候,是获取不到内部组件的,因为此时 exml 文件还没有加载完成,要通过监听 eui.UIEvent.COMPLETE 这个事件获取组件创建完成的消息。
 
像上面这个例子,console 会先输出 createChildren 再输出 onComplete
 
需要注意的是:如果已经在主题中加载了 EXML 文件,会先输出 onComplete 再输出 createChildren.
自定义加载根目录
如何想改变resource的位置 可以用EXML.prefixURL来实现
EXML.prefixURL = "another/";//更改目录位置
var theme = new eui.Theme("resource/default.thm.json", this.stage);
theme.addEventListener(eui.UIEvent.COMPLETE, this.onThemeLoadComplete, this);

EUI库 - 皮肤