Flex定制Tree外观

定制Tree 的外观

Flex 中的Tree是mx前缀的组件,spark组件中没有替代品。
以下解决Flex4 项目中外观的定制化。

更换背景

backgroundColor 和 backgroundAlpha两个样式属性无法在flex4的项目中使用。替代的只有一个属性:contentBackgroundColor,没有找到背景透明度的相关设置功能。

更换图标

图标包括叶子节点的图标、分支节点的图标、分支节点的打开关闭图标
需要分别设置:defaultLeafIcon、folderClosedIcon、folderOpenIcon、disclosureClosedIcon、disclosureOpenIcon属性,它们的值需要是绑定的图标文件Class。

定制项内容

指定Tree的项渲染器,项渲染器要以MXTreeItemRenderer扩展。

<?xml version="1.0" encoding="utf-8"?>
<s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                      xmlns:s="library://ns.adobe.com/flex/spark" 
                      xmlns:mx="library://ns.adobe.com/flex/mx" height="55"     
                      >
    <fx:Script>
        <![CDATA[
            override public function set data(value:Object):void {
                super.data = value;
                if(treeListData.hasChildren)
                {
                    setStyle("fontWeight", 'bold');
                    labelField.text =  treeListData.label;
                }
                else
                {
                    setStyle("fontWeight", 'normal');
                    labelField.text =  treeListData.label;
                }  
            }
        ]]>
    </fx:Script>
    <s:states>
        <s:State name="normal" />            
        <s:State name="hovered" />
        <s:State name="selected" />
    </s:states>
    <s:Rect left="0" right="0" top="0" bottom="0">
        <!--填充颜色-->
        <s:fill>
            <s:SolidColor color="0x0" alpha="0.85" />
        </s:fill>
    </s:Rect>   
    <s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">

        <s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
            <s:fill>
                <s:SolidColor color="0xFF0000" alpha="1" />
            </s:fill>
        </s:Rect>
        <s:Group id="disclosureGroup">
            <s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
        </s:Group>
        <s:BitmapImage source="{treeListData.icon}" />
        <s:Label id="labelField" color="#FFFFFF" fontSize="18" text="{treeListData.label}" paddingTop="2"/>
    </s:HGroup>
    <s:Line left="10" right="10" bottom="0">
        <s:stroke>
            <s:SolidColorStroke color="0x505050"/>
        </s:stroke>
    </s:Line>
</s:MXTreeItemRenderer>

控制项间隙

需要指定Tree的paddingBottom和paddingTop 属性。
如果不需要间距可以将他们都设置为0。

指定Tree的纵向滚动条皮肤

需要指定Tree的verticalScrollBarStyleName,他是一个样式名称。

一个没生效的做法

.MyStyleName 
{
        skinClass:ClassReference("skins.bookdetailVScrollBar.BookDetailVScrollbarSkin")
}

其中的皮肤类修改自spark VScrollBarSkin,其中指定了滑轨、滑块、上下按钮的样式。

这个方法不生效,原因未知。

一个可行的方法

.MyStyleName 
{
    downArrowSkin: ClassReference(null);
    upArrowSkin: ClassReference(null);
trackSkin:ClassReference("skins.bookdetailVScrollBar.BookDetailVScrollBarTackSkin");
    thumbSkin:ClassReference("skins.bookdetailVScrollBar.BookDetailVScrollBarThumSkin")
}

这个样式写法中,指定了滚动条的四个部分。其中上下按钮不需要,注意他们的写法。

背景透明(spark)

contentBackgroundAlpha=”0”
只保留了渲染项的内容和边框。

背景颜色(spark)

contentBackgroundColor

渲染项颜色和背景的关系处理

背景有时候会超过所有渲染项的高度,如果二者颜色不同,看起来非常不舒服。所以可以设置背景颜色,渲染项多数内容透明。

选中项颜色

selectionColor

鼠标经过项颜色

rollOverColor

给Tree提供数据源

采用ArrayCollection

多级数据需要有“children ”属性,其内容应该是该项的子项内容。

控制Tree的展开闭合

方法

expandChildrenOf

expandItem

判断是否开合

isItemOpen

属性

openItems
可以是数组。将其置为空数组,关闭所有开启菜单。这个操作会清空选中项。

渲染项高度固定情况下,让Tree高度自适应

我们的目标是万一内容过多,Tree在占满了可占空间后,自己出现滚动条;在内容渲染后没有达到这个高度前,有多少内容Tree就显示多高。
这里关键要动态设置rowCount属性。
要设置这个属性,我们就不能同时设置Tree的height属性了。
我们监听updateComplete事件,这时更改的内容已经刷新,我们只需要通过rowCount属性告诉Tree:你要显示n行数据就好了。

接下来就是如何计算这个n了,这里采用了一个笨办法,渲染项的高度或者rowHeight 屬性是表示一行的高度,Tree允許的最大高度也是可以得到的,二者做個除法就好了,當然,要向下取整。

一个更完善的版本

上面的方法如遇到多于两级的数据,在孙子目录开启后,tree的尺寸就不对了。问题的原因是:这时tree正在显示多少项没法计算出来,进而无法准确设置rowCount属性。

更好的方法是不再监听updateComplete事件,改而监听itemOpenitemClose事件,这两个事件在项被打开或者关闭的时候调度,在事件类型中,有当前操作的渲染项实例和操作的数据。有了当前操作的数据,我们可以计算出这次操作影响了多少项,然后我们再根据最多能显示多少项、一级数据的个数,决定rowCount合适的值。

以下是主要的代码:

private var showRow:uint;// tree 当前一共有多少项显示

private function findOpenNum(aimItem:Object,openItems:Array):uint
{
    var numChildren:uint=aimItem.children.length;
    for (var i:int = 0; i < aimItem.children.length; i++) 
    {
        var it:Object=aimItem.children[i];
        if(it.children)// 有子
        {
            if(openItems.indexOf(it)!=-1)// 子开
            {
                numChildren+=findOpenNum(it,openItems);
            }
        }
    }
    return numChildren;
}

protected function chapterTree_itemCloseOpenHandler(event:TreeEvent):void
{
    var item:Object=event.item;
    var tree:Tree=event.currentTarget as Tree;
    var numChildren:uint=findOpenNum(item,tree.openItems as Array);
    if(event.type==TreeEvent.ITEM_CLOSE)
    {
        this.showRow-=numChildren;
    }else if(event.type==TreeEvent.ITEM_OPEN)
    {
        this.showRow+=numChildren;
    }
    if(this.showRow>=this.maxRow)
    {
        tree.rowCount=this.maxRow;
    }else
    {
        tree.rowCount=this.showRow;
    }
    trace("变化项个数:"+numChildren+  ",显示个数:"+tree.rowCount);   
}

itemOpenitemClose事件共同的监听方法是chapterTree_itemCloseOpenHandler,这个方法中根据操作的数据获得这次操作在tree中添加或者减少了numChildren项数据,进而计算当前tree中有showRow项处于展示状态,接下来比较showRow和maxRow(显示的内容是否多于能显示的最大项数量),决定显示多少行数据。

其中的findOpenNum方法中,用到了递归,计算影响展开项的数量。这个数量包括当前子项和当前子项的展开项的的数量。

修改tree的dataProvider,需要设置showRow为一级数据的长度。

参考内容

Moving to Flex 4

Using a Spark item renderer with an MX control

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值