,使用自带的Menu MenuBar组件,发现无论怎么定义数据和iconField,菜单和子菜单里面就是不显示图标。最后实在没法子,在网上搜了很多资料,发现必须使用如下形式的定义才可以在菜单里显示图标。
public var _addUser:Class = AppIcons.addUser;
public var _addGroup:Class = AppIcons.addGroup;
public var _sendMessage:Class = AppIcons.sendMessage;
public var _editUser:Class = AppIcons.editUser;
public var _deleteUser:Class = AppIcons.deleteUser;
<mx:MenuBar width=”100%” height=”30″ iconField=”@icon” labelField=”@label”>
<mx:dataProvider>
<mx:XMLList>
<menuitem label=”新建” icon=”_addUser”>
<menuitem label=”联系人” icon=”_addUser”>
<menuitem label=”联系人” icon=”_addUser”/>
<menuitem label=”联系人” icon=”_addUser”/>
</menuitem>
<menuitem label=”分组”/>
</menuitem>
<menuitem label=”加入组” icon=”_addGroup”>
<menuitem label=”组一” />
<menuitem label=”组二”/>
<menuitem label=”组三”/>
<menuitem label=”组四”/>
<menuitem type=”separator”/>
<menuitem label=”新建联系组”/>
</menuitem>
<menuitem label=”发送短消息” icon=”_sendMessage”/>
<menuitem label=”编辑” icon=”_editUser”/>
<menuitem label=”删除” icon=”_deleteUser”/>
</mx:XMLList>
</mx:dataProvider>
</mx:MenuBar>
AppIcons如下定义:
[Bindable]
public class AppIcons
{
[Embed(source="assets/iPhone Phone.png")]
public static var sendInfo:Class
[Embed(source="assets/Address Book.png")]
public static var addressBook:Class
[Embed(source="assets/find.png")]
public static var infoQuery:Class
[Embed(source="assets/user manage.png")]
public static var userManage:Class
[Embed(source="assets/note.png")]
public static var note:Class
[Embed(source="assets/user_add.png")]
public static var addUser:Class;
[Embed(source="assets/group_add.png")]
public static var addGroup:Class;
[Embed(source="assets/phone.png")]
public static var sendMessage:Class;
[Embed(source="assets/user_edit.png")]
public static var editUser:Class;
[Embed(source="assets/user_delete.png")]
public static var deleteUser:Class;
}
但是还是有问题,子菜单里还是没有办法显示图标。于是又开始人肉搜索。可惜搜索了半天也没有结果。没法子,只好老老实实读sdk的源代码。经过不断的调试,发现在MenuBar的getMenuAt方法里面,adobe的同志生成menu的同时没有给其设置document,因此我们在使用menuBar的文档中定义的icon是没有办法被解析的。(参见adobe flex sdk中MenuBar 的getMenuAt方法,itemToIcon方法,以及Menu的makeListData方法,和openSubMenu方法)
于是问题就简单了,只需要在getMenuAt和openSubMenu方法中new Menu的时候给新创建的Menu设置一下document就可以了。重写getMenuAt还比较好做,但是重写openSubMenu就比较麻烦了,它是一个内部的方法,最重要的是没有办法像getMenuAt一样获取到新创建的menu,于是乎又郁闷了。
最后,从iconFunction中找到了答案,在openSubMenu里有一句代码: menu.iconFunction = r.iconFunction;
呵呵,现在,通过简单的重写一下MenuBar就可以得到想要的结果了。
public class MenuBar extends mx.controls.MenuBar
{
public function MenuBar()
{
super();
}
public override function getMenuAt(index:int):Menu
{
var menu:Menu = super.getMenuAt(index);
menu.iconFunction = getMenuIcon;
return menu;
}
private function getMenuIcon(data:Object):Class
{
return super.itemToIcon(data);
}
}
总结一下:
造成这种结果的原因是在sdk MenuBar中的Menu是在动态创建的,无法获取到document,也无法设置iconFunction,所以只要将将document赋予menu就可以使第一级子菜单获得icon,但是二级,三级子菜单还是没有icon,所以就定义一个iconFunction,将MenuBar中ItemToIcon的结果通过这个iconFunction传给子菜单们就可以了,因为MenuBar显然获取了document,可以正确解析定义的icon。