先上图:
如上图所示,多层级列表可以展开其子层级列表.
cocos2dx中有一个TableView,使用它制作列表是一个比较好的选择. 一般使用TableView制作的都是一级列表,这里利用TableView来制作一个多层级列表. 下面直接上代码:
文件CommonList.js: /** * 多级列表 * 默认只渲染一级列表项 * 渲染多级时,子列表数据必须放在sub_items数组中,如 {txt:"item 1",sub_items:[{txt:"sub item 1"},...]} * 且将enable_sub_item设置为true,该值默认为false */ var CommonList = cc.Node.extend({ m_pTView : null, m_pTVSize : null,//视图尺寸 m_pTVRect : null, _sourceData : [],//源数据 _itemData : [],//项数据 _itemSize : [],//项尺寸 _itemPrefab : [],//项资源 enable_sub_item : false, _cellsFreed : [],//空闲项 _viewDelegate: null, ctor : function(view_size) { this._super(); this.init(view_size); }, init : function(view_size) { var self = this; self.m_pTVSize = view_size; self.setContentSize(self.m_pTVSize); self.m_pTVRect = cc.rect(0,self.m_pTVSize.width,self.m_pTVSize.height); self.m_pTView = new cc.TableView(self,self.m_pTVSize); self.m_pTView.setDirection(cc.SCROLLVIEW_DIRECTION_VERTICAL); self.m_pTView.setVerticalFillOrder(cc.TABLEVIEW_FILL_TOPDOWN); self.m_pTView.setDelegate(self); self.addChild(self.m_pTView); }, /** * 加载项资源,必须在loadData之前调用 * @param res * @param width * @param height */ addItemPrefab : function(res,width,height) { this._itemPrefab.push(res); var res_size = cc.size(width,height); this._itemSize.push(res_size); }, /** * 设置外部委托,必须在loadData之前调用 * @param delegate * ->delegate.setItem(node,data) [必须] * ->delegate.onItemClick(node,data) [可无] * ->delegate.onItemPressDown(node,data) [可无] * ->delegate.onItemPressUp(node,data) [可无] */ setDelegate:function (delegate) { this._viewDelegate = delegate; }, enableSubItem : function(tag) { this.enable_sub_item = tag; }, //print printContainer : function () { var size = this.getContainer().getContentSize(); console.log("->current container size : [ " + size.width + "," + size.height + " ]"); var pos = this.getContentOffset(); console.log("->current container pos : [ " + pos.x + "," + pos.y + " ]"); }, reloadData : function (dataSet) { //if(typeof (dataSet) != 'array') { // cc.log("->reloadData(parameter) : invalid parameter"); // return; //} this._sourceData = dataSet; this.resetData(this._sourceData,0); this.loadData(); }, loadData: function() { this._itemData = []; this.getItemData(this._sourceData); this.m_pTView.reloadData(); this.printContainer(); }, getItemData : function(dataSet) { if(!dataSet || dataSet.length === 0) { return; } for(var i = 0,len = dataSet.length; i < len; ++i) { this._itemData.push(dataSet[i]); if(this.enable_sub_item && dataSet[i]._itemOpen && dataSet[i].sub_items) { this.getItemData(dataSet[i].sub_items); } } }, resetData : function(dataSet,itemType) { if(!dataSet || dataSet.length === 0) { return; } for(var i = 0,len = dataSet.length; i < len; ++i) { dataSet[i]._itemLevel = itemType; //层级(从0开始计算) dataSet[i]._itemOpen = false; //展开标记 dataSet[i]._itemIndex = i; //当前层级下的索引(从0开始计算) dataSet[i]._itemCnt = dataSet.length; //当前层级总计算 if(this.enable_sub_item && dataSet[i].sub_items) { this.resetData(dataSet[i].sub_items,itemType + 1); } } }, //tv getContainer : function() { return this.m_pTView.getContainer(); }, getContentOffset: function () { return this.m_pTView.getContentOffset(); }, setContentOffset: function (offset_pos) { this.m_pTView.setContentOffset(offset_pos); }, dequeueCell:function (itemType) { if (this._cellsFreed.length === 0) { return null; } else { var ind = -1; for(var i = 0; i < this._cellsFreed.length; ++i) { if(this._cellsFreed[i]._itemType == itemType) { ind = i; break; } } if(ind == -1) { return null; }else { var cell = this._cellsFreed[ind]; this._cellsFreed.splice(ind,1); return cell; } } }, closeItem: function (data) { data._itemOpen = false; if(data.sub_items && 0 < data.sub_items.length) { for(var ind = 0; ind < data.sub_items.length; ++ind) { this.closeItem(data.sub_items[ind]); } } }, //-----------------------table view callback begin-------------------------// //ok numberOfCellsInTableView: function (table) { return this._itemData.length; }, //ok tableCellSizeForIndex: function (table,idx) { var data = this._itemData[idx]; var size = this._itemSize[data._itemLevel]; if(!size) { cc.log("tableCellSizeForIndex: invalid return value"); } return size; }, //ok tableCellAtIndex: function (table,idx) { //cc.log("cell at index: " + idx); var data = this._itemData[idx]; var itemType = 0; if(this.enable_sub_item && data._itemLevel) { itemType = data._itemLevel; } var res_item = this._itemPrefab[itemType]; if(!res_item) { cc.log("tableCellAtIndex: invalid item prefab"); } var cell = this.dequeueCell(itemType); if(!cell) { cell = new cc.TableViewCell(); var json = ccs.load(res_item); var itemNode = json.node; cell.addChild(itemNode); cell._itemType = itemType; cell._itemNode = itemNode; } if(this._viewDelegate !== null && this._viewDelegate.setItem) { this._viewDelegate.setItem(cell._itemNode,data,cell._itemType); } return cell; }, //ok tableCellTouched:function (table,cell) { var idx = cell.getIdx(); var data = this._itemData[idx]; if(!data) { cc.log("invalid item data"); return; } var reload = false; if(this.enable_sub_item) { if(data.sub_items && 0 < data.sub_items.length) { data._itemOpen = data._itemOpen ? false : true; reload = true; //收缩其所有子项 if(!data._itemOpen) { this.closeItem(data); } }else { data._itemOpen = false; } } //if(this._viewDelegate !== null && this._viewDelegate.onItemClick) { // this._viewDelegate.onItemClick(cell._itemNode,data); //} if(reload) { var ccp_offset = this.getContentOffset(); var size_offset = this.getContainer().getContentSize(); this.loadData(); var size = this.getContainer().getContentSize(); var of_y = size_offset.height - size.height + ccp_offset.y; this.setContentOffset(cc.p(0,of_y)); }else { if(this._viewDelegate !== null && this._viewDelegate.onItemClick) { this._viewDelegate.onItemClick(cell._itemNode,data); } } }, //ok tableCellHighlight:function(table,cell){ var idx = cell.getIdx(); if(this._viewDelegate !== null && this._viewDelegate.onItemPressDown) { var data = this._itemData[idx]; this._viewDelegate.onItemPressDown(cell._itemNode,data); } }, //ok tableCellUnhighlight: function(table,cell){ var idx = cell.getIdx(); if(this._viewDelegate !== null && this._viewDelegate.onItemPressUp) { var data = this._itemData[idx]; this._viewDelegate.onItemPressUp(cell._itemNode, //ok tableCellWillRecycle: function(table,cell) { this._cellsFreed.push(cell); } //-----------------------table view callback end-------------------------// });
使用示例: var list_size = cc.size(560,800); var common_list = new CommonList(list_size); list_layer.addChild(common_list); 设置项资源 common_list.addItemPrefab(res.UIItemPrefab_1,551,54); common_list.addItemPrefab(res.UIItemPrefab_2,54); 设置委托 var list_delegate = {}; list_delegate.setItem = function (node,data) { var level = data._itemLevel; if(level == 0) { var _bg = node.getChildByName("bg"); var _txt_1 = _bg.getChildByName("txt_1"); _txt_1.ignoreContentAdaptWithSize(true); var _txt_2 = _bg.getChildByName("txt_2"); _txt_2.ignoreContentAdaptWithSize(true); _txt_1.setString(data.txt_1); _txt_2.setString(data.txt_2); }else if(level == 1) { var _bg = node.getChildByName("bg"); var _txt_1 = _bg.getChildByName("txt_1"); _txt_1.ignoreContentAdaptWithSize(true); _txt_1.setString(data.txt); } }; list_delegate.onItemClick = function (node,data) { cc.log("->list_delegate.onItemClick"); }; list_delegate.onItemPressDown = function (node,data) { cc.log("->list_delegate.onItemPressDown"); }; list_delegate.onItemPressUp = function (node,data) { cc.log("->list_delegate.onItemPressUp"); }; common_list.setDelegate(list_delegate);
//启用多层级,否则它只是一级列表 common_list.enableSubItem(true);
加载数据,注意数据格式限制,子项必须包含在 sub_items数组中 var list_dataSet = [ {txt_1: "10倍场",txt_2:"9824人",sub_items:[{txt:"房间 1"},{txt:"房间 2"},{txt:"房间 3"},{txt:"房间 4"}]}, {txt_1: "100倍场",txt_2:"754人",sub_items:[{txt:"test"}]}, {txt_1: "1000倍场",txt_2:"2345人",sub_items:[{txt:"test 1"},{txt:"test 2"},{txt:"test 3"}]}, {txt_1: "10000倍场",txt_2:"678人",sub_items:[{txt:"挑战 1"},{txt:"挑战 2"}]} ]; common_list.reloadData(list_dataSet);
至此,恭喜你创建出多层级列表. (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|