在cocos2dx里,cctableview是不支持作动画的,而我的项目里就需要让tableview作动画。所以我就继承tableview,改写其中的一些方法!
1 // 2 // WdTableView.h 3 // tttt 4 // 5 // Created by Windy on 12/27/13. 6 // 7 // 8 9 #ifndef __tttt__WdTableView__ 10 #define __tttt__WdTableView__ 11 12 #include "cocos2d.h" 13 #include "cocos-ext.h" 14 15 class WdTableView 16 : public cocos2d::extension::CCTableView, /** 继承cctableview */ 17 public cocos2d::CCRGBAProtocol /** 继承rgb通道, 使该控件能够做渐隐和渐显 */ 18 { 19 /// @{ 20 /// @name 创建方法 21 public: 22 WdTableView(); 23 virtual ~WdTableView(); 24 /** 25 * @brief 根据数据代理和大小去创建一个table 26 * 27 * @Modified by chenbaicai at 2013-12-27 18:34:02 28 * @param dataSource 数据代理 29 * @param size 控件大小 30 * 31 * @return 创建好的table大小 32 **/ 33 static WdTableView* create(cocos2d::extension::CCTableViewDataSource* dataSource, cocos2d::CCSize size); 34 35 /** 36 * @brief 根据数据代理的大小,主要容器去创建一个table 37 * 38 * @Modified by chenbaicai at 2013-12-27 18:36:46 39 * @param dataSource 数据代理 40 * @param size 控件大小 41 * @param container 主要容器(如果自己设置,本类不负责retain) 42 * 43 * @return 返回一个创建成功的table 44 **/ 45 static WdTableView* create(cocos2d::extension::CCTableViewDataSource* dataSource, cocos2d::CCSize size, cocos2d::CCNode *container); 46 47 /// @} end 创建方法 48 /// @{ 49 /// @name 属性方法 50 /** 51 * @brief 动态插入cell 52 * 53 * @Modified by chenbaicai at 2013-12-27 18:42:21 54 * @param idx 下标位置 55 * @param insertDelayTime 这个delaytime只是为了跟其他动画配合,可以独立一个函数 56 **/ 57 void insertCellAtIndex(unsigned int idx, float insertDelayTime); 58 /** 59 * @brief 某个点下cell下标 60 * 61 * @Modified by chenbaicai at 2013-12-27 18:46:40 62 * @param x x 63 * @param y y 64 * 65 * @return 下标index 66 **/ 67 int indexFromPoint(int x, int y); 68 69 /** 70 * @brief 返回指定下标的位置 71 * 72 * @Modified by chenbaicai at 2013-12-27 18:47:17 73 * @param index 下标 74 * 75 * @return 坐标 76 **/ 77 cocos2d::CCPoint pointFromIndex(int index); 78 79 /** 80 * @brief 把cell放置到指定的index下 81 * 82 * @Modified by chenbaicai at 2013-12-27 18:47:46 83 * @param index 要移动到的目标的下标 84 * @param cell 当前要移动的cell 85 * @param animate 是否要作动画 86 **/ 87 void _setIndexForCell(unsigned int index, cocos2d::extension::CCTableViewCell *cell, bool animate); 88 89 /** 90 * @brief 移除指定下标下的cell 91 * 92 * @Modified by chenbaicai at 2013-12-27 18:50:36 93 * @param idx 要移除的cell的下标 94 **/ 95 void removeCellAtIndex(unsigned int idx); 96 97 /** 98 * @brief 作推迟插入cell的动画时,回调插入cell的方法 99 * 100 * @Modified by chenbaicai at 2013-12-27 18:52:04 101 **/ 102 void delayInsertCell(); 103 104 105 /// @note 这些都是rgb通道的方法 106 /** 107 * Changes the color with R,G,B bytes 108 * 109 * @param color Example: ccc3(255,100,0) means R=255, G=100, B=0 110 */ 111 virtual void setColor(const cocos2d::ccColor3B& color); 112 113 /** 114 * Returns color that is currently used. 115 * 116 * @return The ccColor3B contains R,G,B bytes. 117 */ 118 virtual const cocos2d::ccColor3B& getColor(void); 119 120 /** 121 * Returns the displayed color. 122 * 123 * @return The ccColor3B contains R,G,B bytes. 124 */ 125 virtual const cocos2d::ccColor3B& getDisplayedColor(void); 126 127 /** 128 * Returns the displayed opacity. 129 * 130 * @return The opacity of sprite, from 0 ~ 255 131 */ 132 virtual GLubyte getDisplayedOpacity(void); 133 /** 134 * Returns the opacity. 135 * 136 * The opacity which indicates how transparent or opaque this node is. 137 * 0 indicates fully transparent and 255 is fully opaque. 138 * 139 * @return The opacity of sprite, from 0 ~ 255 140 */ 141 virtual GLubyte getOpacity(void); 142 143 /** 144 * Changes the opacity. 145 * 146 * @param value Goes from 0 to 255, where 255 means fully opaque and 0 means fully transparent. 147 */ 148 virtual void setOpacity(GLubyte opacity); 149 150 // optional 151 /** 152 * Changes the OpacityModifyRGB property. 153 * If thie property is set to true, then the rendered color will be affected by opacity. 154 * Normally, r = r * opacity/255, g = g * opacity/255, b = b * opacity/255. 155 * 156 * @param bValue true then the opacity will be applied as: glColor(R,G,B,opacity); 157 * false then the opacity will be applied as: glColor(opacity, opacity, opacity, opacity); 158 */ 159 virtual void setOpacityModifyRGB(bool bValue); 160 /** 161 * Returns whether or not the opacity will be applied using glColor(R,G,B,opacity) 162 * or glColor(opacity, opacity, opacity, opacity) 163 * 164 * @return Returns opacity modify flag. 165 */ 166 virtual bool isOpacityModifyRGB(void); 167 /** 168 * whether or not color should be propagated to its children. 169 */ 170 virtual bool isCascadeColorEnabled(void); 171 virtual void setCascadeColorEnabled(bool cascadeColorEnabled); 172 173 /** 174 * recursive method that updates display color 175 */ 176 virtual void updateDisplayedColor(const cocos2d::ccColor3B& color); 177 178 /** 179 * whether or not opacity should be propagated to its children. 180 */ 181 virtual bool isCascadeOpacityEnabled(void); 182 virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled); 183 184 /** 185 * recursive method that updates the displayed opacity. 186 */ 187 virtual void updateDisplayedOpacity(GLubyte opacity); 188 /// @} end 属性方法 189 190 /// @{ 191 /// @name 属性 192 public: 193 int m_indexToInsert; // 延时插入新数据时备份 194 protected: 195 GLubyte _displayedOpacity; /// 展示的透明度 196 GLubyte _realOpacity; /// 真实透明度 197 cocos2d::ccColor3B _displayedColor;/// 真实色彩 198 cocos2d::ccColor3B _realColor; /// 展示色彩 199 bool _cascadeColorEnabled; /// 是否开启色彩变幻 200 bool _cascadeOpacityEnabled; /// 是否开启透明渐变 201 /// @} end 属性 202 }; 203 #endif /* defined(__tttt__WdTableView__) */
1 // 2 // WdTableView.cpp 3 // tttt 4 // 5 // Created by Windy on 12/27/13. 6 // 7 // 8 9 #include "WdTableView.h" 10 11 USING_NS_CC; 12 USING_NS_CC_EXT; 13 14 15 /// 初始化部分成员属性 16 WdTableView::WdTableView() 17 : _displayedOpacity(255) 18 , _realOpacity(255) 19 , _displayedColor(ccWHITE) 20 , _realColor(ccWHITE) 21 , _cascadeColorEnabled(false) 22 , _cascadeOpacityEnabled(false) 23 { 24 } 25 WdTableView::~WdTableView(){ 26 27 } 28 29 WdTableView* WdTableView::create(CCTableViewDataSource* dataSource, CCSize size) 30 { 31 return WdTableView::create(dataSource, size, NULL); 32 } 33 34 WdTableView* WdTableView::create(CCTableViewDataSource* dataSource, CCSize size, CCNode *container) 35 { 36 WdTableView *table = new WdTableView(); 37 /// 以下方法都是利用父类来作出初始化的 38 table->initWithViewSize(size, container); 39 table->autorelease(); 40 table->setDataSource(dataSource); 41 table->_updateCellPositions(); 42 table->_updateContentSize(); 43 44 return table; 45 } 46 void WdTableView::insertCellAtIndex(unsigned int idx, float insertDelayTime) 47 { 48 if (idx == CC_INVALID_INDEX) 49 { 50 return; 51 } 52 53 unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this); 54 if (0 == uCountOfItems || idx > uCountOfItems-1) 55 { 56 return; 57 } 58 59 CCTableViewCell* cell = NULL; 60 int newIdx = 0; 61 62 cell = (CCTableViewCell*)m_pCellsUsed->objectWithObjectID(idx); 63 m_pIndices->clear(); 64 if (cell) 65 { 66 newIdx = m_pCellsUsed->indexOfSortedObject(cell); 67 68 for (int i = 0; i < (int)newIdx; ++i) { 69 cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i); 70 m_pIndices->insert(cell->getIdx()); 71 } 72 73 for (unsigned int i=newIdx; i<m_pCellsUsed->count(); i++) 74 { 75 cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i); 76 int ni = cell->getIdx()+1; 77 this->_setIndexForCell(ni, cell, true); 78 m_pIndices->insert(ni); 79 } 80 } 81 /// 是否要作推迟插入cell 82 if (insertDelayTime > 0) { 83 m_indexToInsert = idx; 84 /// 动画,如果有需要。,可以自己抽出来改 85 CCDelayTime* delay = CCDelayTime::create(0.2f); 86 CCCallFunc* call = CCCallFunc::create(this, callfunc_selector(WdTableView::delayInsertCell)); 87 CCSequence* seq = CCSequence::createWithTwoActions(delay, call); 88 this->runAction(seq); 89 } else { 90 cell = m_pDataSource->tableCellAtIndex(this, idx); 91 this->_setIndexForCell(idx, cell, false); 92 this->_addCellIfNecessary(cell); 93 94 this->_updateCellPositions(); 95 this->_updateContentSize(); 96 } 97 } 98 99 void WdTableView::delayInsertCell() 100 { 101 /// 重新更新一下整个table 102 CCTableViewCell* cell = m_pDataSource->tableCellAtIndex(this, m_indexToInsert); 103 this->_setIndexForCell(m_indexToInsert, cell, false); 104 this->_addCellIfNecessary(cell); 105 106 this->_updateCellPositions(); 107 this->_updateContentSize(); 108 } 109 110 void WdTableView::removeCellAtIndex(unsigned int idx) 111 { 112 if (idx == CC_INVALID_INDEX) 113 { 114 return; 115 } 116 117 unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(static_cast<CCTableView*>(this)); 118 if (0 == uCountOfItems || idx > uCountOfItems-1) 119 { 120 return; 121 } 122 123 unsigned int newIdx = 0; 124 125 CCTableViewCell* cell = this->cellAtIndex(idx); 126 if (!cell) 127 { 128 return; 129 } 130 131 newIdx = m_pCellsUsed->indexOfSortedObject(cell); 132 133 //remove first 134 this->_moveCellOutOfSight(cell); 135 136 137 this->_updateCellPositions(); 138 // [m_pIndices shiftIndexesStartingAtIndex:idx+1 by:-1]; 139 140 // 重新修改indices的值 141 m_pIndices->clear(); 142 for (int i = 0; i < (int)newIdx; ++i) { 143 cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i); 144 m_pIndices->insert(cell->getIdx()); 145 } 146 147 for (int i=(int)m_pCellsUsed->count()-1; i >= (int)newIdx; --i) 148 { 149 cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(i); 150 int ni = cell->getIdx()-1; 151 this->_setIndexForCell(ni, cell, true); 152 m_pIndices->insert(ni); 153 } 154 155 // 补充最后一个元素 156 if (m_pCellsUsed->count() > 0) { 157 cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1); 158 int index = cell->getIdx() + 1; 159 if (index < (int)m_pDataSource->numberOfCellsInTableView(this)) { 160 // 超出显示范围,更新 161 this->updateCellAtIndex(index); 162 163 // 更新完毕,重新取最后一个cell 164 cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(m_pCellsUsed->count() - 1); 165 CCPoint dst = cell->getPosition(); 166 cell->setPositionX(dst.x + m_vCellsPositions[index] - m_vCellsPositions[index - 1]); 167 CCMoveTo* moveTo = CCMoveTo::create(0.2f, dst); 168 cell->runAction(moveTo); 169 } 170 } 171 } 172 173 void WdTableView::_setIndexForCell(unsigned int index, CCTableViewCell *cell, bool animate) 174 { 175 if (!cell) { 176 return; 177 } 178 cell->setAnchorPoint(ccp(0.0f, 0.0f)); 179 CCPoint pt = this->_offsetFromIndex(index); 180 if (animate) { 181 CCMoveTo* moveTo = CCMoveTo::create(0.2f, pt); 182 cell->runAction(moveTo); 183 } else { 184 cell->setPosition(pt); 185 } 186 187 cell->setIdx(index); 188 } 189 190 int WdTableView::indexFromPoint(int x, int y) 191 { 192 CCPoint offset = this->convertToNodeSpace(ccp(x, y)); 193 CCPoint of2 = getContentOffset(); 194 offset.x -= of2.x; 195 offset.y -= of2.y; 196 int index = _indexFromOffset(offset); 197 CCPoint roffset = _offsetFromIndex(index); 198 CCSize size = m_pDataSource->cellSizeForTable(this); 199 if (offset.x - roffset.x >= size.width / 2) { 200 ++index; 201 } 202 203 if (index < 0) { 204 index = 0; 205 } 206 207 int amount = m_pDataSource->numberOfCellsInTableView(this); 208 if (index > amount) { 209 index = amount; 210 } 211 return index; 212 } 213 214 CCPoint WdTableView::pointFromIndex(int index) 215 { 216 CCPoint offset = __offsetFromIndex(index); 217 CCPoint of2 = getContentOffset(); 218 offset.x += of2.x; 219 offset.y += of2.y; 220 221 CCPoint pt = convertToWorldSpace(offset); 222 pt = getParent()->convertToNodeSpace(pt); 223 return pt; 224 } 225 226 #pragma mark - 227 #pragma mark CCRGBAProtocol 228 /** 229 * Changes the color with R,G,B bytes 230 * 231 * @param color Example: ccc3(255,100,0) means R=255, G=100, B=0 232 */ 233 void WdTableView::setColor(const ccColor3B& color){ 234 _displayedColor = _realColor = color; 235 236 if (_cascadeColorEnabled) 237 { 238 ccColor3B parentColor = ccWHITE; 239 CCRGBAProtocol *parent = dynamic_cast<CCRGBAProtocol*>(m_pParent); 240 if (parent && parent->isCascadeColorEnabled()) 241 { 242 parentColor = parent->getDisplayedColor(); 243 } 244 245 updateDisplayedColor(parentColor); 246 } 247 } 248 249 /** 250 * Returns color that is currently used. 251 * 252 * @return The ccColor3B contains R,G,B bytes. 253 */ 254 const ccColor3B& WdTableView::getColor(void){ 255 return _realColor; 256 } 257 258 /** 259 * Returns the displayed color. 260 * 261 * @return The ccColor3B contains R,G,B bytes. 262 */ 263 const ccColor3B& WdTableView::getDisplayedColor(void){ 264 return _displayedColor; 265 } 266 267 /** 268 * Returns the displayed opacity. 269 * 270 * @return The opacity of sprite, from 0 ~ 255 271 */ 272 GLubyte WdTableView::getDisplayedOpacity(void){ 273 return _displayedOpacity; 274 } 275 /** 276 * Returns the opacity. 277 * 278 * The opacity which indicates how transparent or opaque this node is. 279 * 0 indicates fully transparent and 255 is fully opaque. 280 * 281 * @return The opacity of sprite, from 0 ~ 255 282 */ 283 GLubyte WdTableView::getOpacity(void){ 284 return _realOpacity; 285 } 286 287 /** 288 * Changes the opacity. 289 * 290 * @param value Goes from 0 to 255, where 255 means fully opaque and 0 means fully transparent. 291 */ 292 void WdTableView::setOpacity(GLubyte opacity){ 293 _displayedOpacity = _realOpacity = opacity; 294 295 if (_cascadeOpacityEnabled) 296 { 297 GLubyte parentOpacity = 255; 298 CCRGBAProtocol* pParent = dynamic_cast<CCRGBAProtocol*>(m_pParent); 299 if (pParent && pParent->isCascadeOpacityEnabled()) 300 { 301 parentOpacity = pParent->getDisplayedOpacity(); 302 } 303 this->updateDisplayedOpacity(parentOpacity); 304 } 305 if (opacity == 0) { 306 setVisible(false); 307 } 308 else 309 setVisible(true); 310 } 311 312 // optional 313 314 /** 315 * whether or not color should be propagated to its children. 316 */ 317 bool WdTableView::isCascadeColorEnabled(void){ 318 return _cascadeColorEnabled; 319 } 320 void WdTableView::setCascadeColorEnabled(bool cascadeColorEnabled){ 321 _cascadeColorEnabled = cascadeColorEnabled; 322 } 323 324 /** 325 * recursive method that updates display color 326 */ 327 void WdTableView::updateDisplayedColor(const ccColor3B& parentColor){ 328 329 _displayedColor.r = _realColor.r * parentColor.r/255.0; 330 _displayedColor.g = _realColor.g * parentColor.g/255.0; 331 _displayedColor.b = _realColor.b * parentColor.b/255.0; 332 333 if (_cascadeColorEnabled) 334 { 335 CCObject *obj = NULL; 336 CCARRAY_FOREACH(m_pChildren, obj) 337 { 338 CCRGBAProtocol *item = dynamic_cast<CCRGBAProtocol*>(obj); 339 if (item) 340 { 341 item->updateDisplayedColor(_displayedColor); 342 } 343 } 344 } 345 } 346 347 /** 348 * whether or not opacity should be propagated to its children. 349 */ 350 bool WdTableView::isCascadeOpacityEnabled(void){ 351 return _cascadeOpacityEnabled; 352 } 353 void WdTableView::setCascadeOpacityEnabled(bool cascadeOpacityEnabled){ 354 _cascadeOpacityEnabled = cascadeOpacityEnabled; 355 } 356 357 /** 358 * recursive method that updates the displayed opacity. 359 */ 360 void WdTableView::updateDisplayedOpacity(GLubyte parentOpacity){ 361 _displayedOpacity = _realOpacity * parentOpacity/255.0; 362 363 if (_cascadeOpacityEnabled) 364 { 365 CCObject* _s_pcell = NULL; 366 CCARRAY_FOREACH(m_pCellsUsed, _s_pcell) 367 { 368 CCObject* pObj = NULL; 369 CCTableViewCell* cell = dynamic_cast<CCTableViewCell*>(_s_pcell); 370 371 if (cell) { 372 CCARRAY_FOREACH(cell->getChildren(), pObj) 373 { 374 CCRGBAProtocol* item = dynamic_cast<CCRGBAProtocol*>(pObj); 375 if (item) 376 { 377 item->setOpacity(_displayedOpacity); 378 } 379 } 380 } 381 } 382 } 383 } 384 385 bool WdTableView::isOpacityModifyRGB(void){ 386 return false; 387 } 388 void WdTableView::setOpacityModifyRGB(bool bValue){ 389 CC_UNUSED_PARAM(bValue); 390 }
上面是我写的代码,规范性不强,大神可以自愿改动!欢迎提供修改意见!代码里已经有注解了!
应网友要求,下面这个classes是用2.2.3写的demo,可以从这里下载。创建一个全新的项目,直接覆盖到classes下导入工程就可以用了!