1.首先得明白一点,FLEX4的TREE接受的是XML类型的数据,所以无论以何种方式获得XML数据,TREE通过dataProvider=XMLDATA和labelField=@viewname都可以显示出来一棵树
第一种方式,读取本地或远程XML文件
XML文件的格式,大致如下
<?xml version="1.0" encoding="UTF-8"?>
<node label='所有分类'>
<node label='中国' value="http://www.baidu.com">
<node label='河南' value="http://www.youdao.com" >
<node label='信阳' />
<node label='南阳'/>
</node>
<node label='河北'>
<node label='保定'/>
<node label='衡水'/>
</node>
<node label='湖南' >
<node label='长沙'/>
<node label='湘潭'/>
</node>
<node label='湖北'>
<node label='武汉'/>
<node label='仙桃'/>
</node>
</node>
</node>
针对上面这个XML格式的文件,Flex4的TREE解析后显示的话会从第二个节点开始解析也即中国那个节点
这种方式的代码我贴出来,大家看下
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
creationComplete="SrvTreeList.send();init()">
<fx:Style>
Tree {
folderClosedIcon: ClassReference(null);
folderOpenIcon: ClassReference(null);
}
</fx:Style>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
var XMLTreeList:XML;
protected function treeService_resultHandler(event:ResultEvent):void
{
//先把数据取出来交给XML,再交给dataProvider,因为dataProvider不能直接解析String为XML
XMLTreeList=XML(SrvTreeList.lastResult.toString());
MusicTypeTree.dataProvider=XMLTreeList;
}
//这里我写了一个右键菜单
public function init():void{
var item: ContextMenuItem=new ContextMenuItem("添加");
var menu:ContextMenu=new ContextMenu();
menu.customItems.push(item);
MusicTypeTree.contextMenu=menu;
}
protected function tree1_clickHandler(event:MouseEvent):void
{
if(MusicTypeTree.selectedItem.hasOwnProperty("@value" ))
{ //如果某节点中含有VALUE属性,那么就是先跳转页面
navigateToURL(new URLRequest(MusicTypeTree.selectedItem.@value));
} else
{
//没有那就展开,如果展开了就收缩
MusicTypeTree.expandItem(MusicTypeTree.selectedItem,!MusicTypeTree.isItemOpen(MusicTypeTree.selectedItem),true);
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<s:HTTPService id="SrvTreeList" url="data/tree.xml" result="treeService_resultHandler(event)" useProxy="false" resultFormat="xml" />
</fx:Declarations>
<!--@label这个非常重要,指定要显示的标题为XML重的label属性值。记住要显示树,httpService的send方法要在组件创建完成后被调用-->
<mx:Tree x="20" y="10" click="tree1_clickHandler(event)" id="MusicTypeTree"
left="5" right="5"
showRoot="false"
labelField="@label"
bottom="5" top="40"
></mx:Tree>
</s:Application>
第二种方式:将XML内容写到<fx:mxl>标签里面
这种方式我们来看看
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
creationComplete="init()">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ICollectionView;
import mx.events.ListEvent;
private function tree_itemClick(evt:ListEvent):void {
var item:Object = Tree(evt.currentTarget).selectedItem;
if (tree.dataDescriptor.isBranch(item)) {
tree.expandItem(item, !tree.isItemOpen(item), true);
}
}
private function tree_labelFunc(item:XML):String {
var children:ICollectionView;
var suffix:String = "";
if (tree.dataDescriptor.isBranch(item)) {
children = tree.dataDescriptor.getChildren(item);
suffix = " (" + children.length + ")";
}
return item[tree.labelField] + suffix;
}
]]>
</fx:Script>
<fx:Declarations>
<fx:XML id="dp">
<root>
<folder label="One">
<folder label="One.A">
<item label="One.A.1" />
<item label="One.A.2" />
<item label="One.A.3" />
<item label="One.A.4" />
<item label="One.A.5" />
</folder>
<item label="One.1" />
<item label="One.2" />
</folder>
<folder label="Two">
<item label="Two.1" />
<folder label="Two.A">
<item label="Two.A.1" />
<item label="Two.A.2" />
</folder>
</folder>
</root>
</fx:XML>
</fx:Declarations>
<mx:Tree id="tree"
dataProvider="{dp}"
showRoot="false"
labelField="@label"
labelFunction="tree_labelFunc"
width="742"
rowCount="6"
itemClick="tree_itemClick(event);" x="14" y="12" height="359"/>
</s:Application>
itemClick方法可以和labelFuntion可以不写,正常的话不写方法就能显示TREE的树形结构了
第三:再看一个例子
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<fx:XMLList id="treeData">
<node label="Mail Box">
<node label="Inbox">
<node label="Marketing"/>
<node label="Product Management"/>
<node label="Personal"/>
</node>
<node label="Outbox">
<node label="Professional"/>
<node label="Personal"/>
</node>
<node label="Spam"/>
<node label="Sent"/>
</node>
</fx:XMLList>
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var selectedNode:XML;
// Event handler for the Tree control change event.
public function treeChanged(event:Event):void {
selectedNode=Tree(event.target).selectedItem as XML;
}
]]>
</fx:Script>
<mx:Panel title="Tree Control Example" height="75%" width="75%"
paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">
<mx:Label width="100%" color="blue"
text="Select a node in the Tree control."/>
<mx:HDividedBox width="100%" height="100%">
<mx:Tree id="myTree" width="50%" height="100%" labelField="@label"
showRoot="false" dataProvider="{treeData}" change="treeChanged(event)"/>
<mx:TextArea height="100%" width="50%"
text="Selected Item: {selectedNode.@label}"/>
</mx:HDividedBox>
</mx:Panel>
</s:Application>
第四,到目前为止,应该可以看出来了XML的显示格式了,如果获取XML文件那么结果要转换成为
var xmlList:XML=XML(event.result.toString());
mytree.dataProvider=xmlList;
要么就是<mx:Tree dataProvider="{xmlList}" >
那么就是
<fx:xml id="xmlid"></fx:xml>
<mx:Tree dataProvider="{xmlid}">
这么多的方式都可以把数据填充到TREE中去
第五:来一个增删拖拽展开,收缩的示例,这里先不涉及到后台,下一篇文章会讲到TREE与JAVA后台数据库的交互操作
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
creationComplete="SrvTreeList.send();init()">
<fx:Style>
Tree {
folderClosedIcon: ClassReference(null);
folderOpenIcon: ClassReference(null);
}
</fx:Style>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.events.DragEvent;
import mx.managers.DragManager;
import mx.rpc.events.ResultEvent;
var XMLTreeList:XML;
protected function treeService_resultHandler(event:ResultEvent):void
{
//先把数据取出来交给XML,再交给dataProvider,因为dataProvider不能直接解析String为XML
XMLTreeList=XML(SrvTreeList.lastResult.toString());
MusicTypeTree.dataProvider=XMLTreeList;
}
public function init():void{
var item: ContextMenuItem=new ContextMenuItem("添加");
var menu:ContextMenu=new ContextMenu();
menu.customItems.push(item);
MusicTypeTree.contextMenu=menu;
}
protected function tree1_clickHandler(event:MouseEvent):void
{
if(MusicTypeTree.selectedItem.hasOwnProperty("@value" ))
{
var u:URLRequest=new URLRequest(MusicTypeTree.selectedItem.@value);
//navigateToURL(new URLRequest(MusicTypeTree.selectedItem.@value));
navigateToURL(u);
} else
{
//没有那就展开,如果展开了就收缩
MusicTypeTree.expandItem(MusicTypeTree.selectedItem,!MusicTypeTree.isItemOpen(MusicTypeTree.selectedItem),true);
}
}
//添加兄弟节点
protected function addBefore():void
{
var xml:XML=MusicTypeTree.selectedItem as XML;
var text:String=nextName.text;
if(xml!=null && text.length>0) {
var parent:XML=xml.parent();
if(parent!=null) {
var child:XML=new XML("<node foddersortName=\"\" foddersortId=\"\" parentid=\"\" />");
child.@foddersortName=text;
parent.insertChildBefore(xml,child);
} else {
Alert.show("不能选中根节点");
}
} else {
Alert.show("需要先选中节点和填入文字");
}
}
protected function addAfter():void
{
var xml:XML=MusicTypeTree.selectedItem as XML;
var text:String=nextName.text;
if(xml!=null && text.length>0) {
var parent:XML=xml.parent();
if(parent!=null) {
var child:XML=new XML("<node foddersortName=\"\" foddersortId=\"\" parentid=\"\" />");
child.@foddersortName=text;
parent.insertChildAfter(xml,child);
} else {
Alert.show("不能选中根节点");
}
} else {
Alert.show("需要先选中节点和填入文字");
}
}
protected function addSon():void
{
var xml:XML=MusicTypeTree.selectedItem as XML;
var text:String=nextName.text;
if(xml!=null && text.length>0) {
var parent:XML=xml.parent();
var child:XML=new XML("<node foddersortName=\"\" foddersortId=\"\" parentid=\"\" />");
child.@foddersortName=text;
xml.appendChild(child);
MusicTypeTree.expandChildrenOf(xml,true);
} else {
Alert.show("需要先选中节点和填入文字");
}
}
protected function editNode():void
{
var xml:XML=MusicTypeTree.selectedItem as XML;
var text:String=nextName.text;
if(xml!=null && text.length>0) {
xml.@foddersortName=text;
} else {
Alert.show("需要先选中节点和填入文字");
}
}
protected function deleteNode():void
{
var xml:XML=MusicTypeTree.selectedItem as XML;
if(xml!=null) {
var list:Array=MusicTypeTree.selectedItems as Array;
for(var k:int=0;k<list.length;k++) {
xml=list[k] as XML;
var parent:XML=xml.parent();
if(parent!=null) {
var children:XMLList=parent.children();
for(var i:int=0;i<children.length();i++) {
if(children[i]==xml) {
delete children[i];
break;
}
}
} else {
Alert.show("不能选中根节点");
}
}
} else {
Alert.show("需要先选中节点");
}
}
protected function selectNode():void
{
var text:String=nextName.text;
if(text.length>0) {
var items:Array=[];
var list:XMLList=new XMLList();
list[0]=MusicTypeTree.dataProvider[0];
searchItems(list,text,items);
MusicTypeTree.selectedItems=items;
} else {
Alert.show("输入查找的文字");
}
}
private function searchItems(list:XMLList,find:String,items:Array):void {
for(var i:int=0;i<list.length();i++) {
var one:XML=list[i];
var label:String=one.@foddersortName;
if(label!=null && label.indexOf(find)>=0) {
items.push(one);
}
searchItems(one.children(),find,items);
}
}
protected function closeAll():void{
MusicTypeTree.openItems=[];
}
protected function openAll():void{
MusicTypeTree.expandChildrenOf(MusicTypeTree.selectedItem,true);
}
protected function MusicTypeTree_dragEnterHandler(event:DragEvent):void
{
Alert.show(event.target.@foddersortName);
DragManager.acceptDragDrop(UIComponent(event.currentTarget));
}
protected function MusicTypeTree_dragOverHandler(event:DragEvent):void
{
// r is the visible index in the tree
var dropTarget:Tree = Tree(event.currentTarget);
var r:int = dropTarget.calculateDropIndex(event);
MusicTypeTree.selectedIndex = r;
// retrieving the newly selected node, you can examine it and decide to tell
// the user the drop is invalid by changing the feedback.
var node:XML = MusicTypeTree.selectedItem as XML;
if( node.@foddersortName == "中国" ) {
DragManager.showFeedback(DragManager.NONE);
return;
}
// the type of drop - copy, link, or move can be reflected in the feedback as well.
// Here the control and shift keys determine that action.
if (event.ctrlKey)
DragManager.showFeedback(DragManager.COPY);
else if (event.shiftKey)
DragManager.showFeedback(DragManager.LINK);
else {
DragManager.showFeedback(DragManager.MOVE);
}
}
protected function MusicTypeTree_dragDropHandler(event:DragEvent):void
{
var xml:XML=MusicTypeTree.selectedItem as XML;
Alert.show(xml.@foddersortName);
// var ds:DragSource = event.dragSource;
// var dropTarget:Tree = Tree(event.currentTarget);
// // retrieve the data associated with the "items" format. This will be the data that
// // the dragInitiator has copied into the DragSource.
// var items:Array = ds.dataForFormat("items") as Array;
// // determine where in the tree the drop occurs and select that node by the index; followed by
// // retrieving the node itself.
// var r:int = MusicTypeTree.calculateDropIndex(event);
// MusicTypeTree.selectedIndex = r;
// var node:XML = MusicTypeTree.selectedItem as XML;
// var p:*;
// // if the selected node has children (it is type==city),
// // then add the items at the beginning
// if( MusicTypeTree.dataDescriptor.hasChildren(node) ) {
// p = node;
// r = 0;
// } else {
// p = node.parent();
// }
// // taking all of the items in the DragSouce, insert them into the
// // tree using parent p.
// for(var i:Number=0; i < items.length; i++) {
// var insert:XML = <node />;
// insert.@foddersortName= items[i];
// //insert.@type = "restaurant";
// MusicTypeTree.dataDescriptor.addChildAt(p, insert, r+i);
// }
}
protected function MusicTypeTree_dragCompleteHandler(event:DragEvent):void
{
MusicTypeTree.selectedIndex = -1;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<s:HTTPService id="SrvTreeList" url="data/tree.xml" result="treeService_resultHandler(event)" useProxy="false" resultFormat="xml" />
</fx:Declarations>
<!--@label这个非常重要,指定要显示的标题为XML重的label属性值。记住要显示树,httpService的send方法要在组件创建完成后被调用-->
<mx:Tree click="tree1_clickHandler(event)" id="MusicTypeTree"
left="5" right="845"
showRoot="false"
labelField="@foddersortName"
bottom="243" top="40"
dragEnabled="true"
dropEnabled="true"
allowMultipleSelection="true"
allowDragSelection="true"
dragDrop="MusicTypeTree_dragDropHandler(event)"
dragEnter="MusicTypeTree_dragEnterHandler(event)"
></mx:Tree>
<s:TextInput id="nextName" x="432" y="40"/>
<s:Button x="443" y="82" label="增加为哥" click="addBefore()"/>
<s:Button x="443" y="111" label="增加为弟" click="addAfter()"/>
<s:Button x="444" y="144" click="addSon()" label="增加为孩子"/>
<s:Button x="444" y="178" click="editNode()" label="修改节点"/>
<s:Button x="444" y="211" click="deleteNode()" label="删除节点"/>
<s:Button x="443" y="244" click="selectNode()" label="选择节点"/>
<s:Button x="443" y="277" click="closeAll()" label="全部收缩"/>
<s:Button x="443" y="306" click="openAll()" label="全部展开"/>
</s:Application>