您好,欢迎访问一九零五行业门户网

cocos2dx 3.2键盘操控的列表页的初步实现

一、实现后的目标效果 有图有真相,首先上实现了的效果。 二 、思路 由于要加载较多数据,那么为了使得界面更近流畅,我采用tableview,其中他的cell是可以复用的。创建10000个也是秒秒钟的事情。 那么使用上下排列的tableview,每个cell自定义三个item即可
一、实现后的目标效果有图有真相,首先上实现了的效果。
二 、思路由于要加载较多数据,那么为了使得界面更近流畅,我采用tableview,其中他的cell是可以复用的。创建10000个也是秒秒钟的事情。
那么使用上下排列的tableview,每个cell自定义三个item即可,当然也可以n个,可以自己写好接口。
由于我们想使得tableview可以滚动到指定的cell位置,也就是一格一格滚动,那么我们最好自定义一个tableview继承于系统的tableview.
三 、实现步骤如果你对于tableview不太熟悉,建议先看官方testcpp例子.
如果你比较熟悉,那么我就不废话,继续往下讲了。
我们先来自定义一个tableviewcell。也就是自定义一行的内容。我相信这个非常简单。
四、准备工作我们先来自定义一个tableviewcell。也就是自定义一行的内容。我相信这个非常简单。
cell头文件
class xtableviewcell : public cocos2d::extension::tableviewcell{public: xtableviewcell(); virtual ~xtableviewcell(); create_func(xtableviewcell); /************************************************************************/ /* update item by data */ /************************************************************************/ bool updateitemdata(const unsigned int tag, const std::string icon, const std::string name, const std::string size, const std::string downnum, const std::string score); bool setitemselected(const unsigned int tag,bool isseleted);cc_constructor_access: bool init(); //bool init bool initlayout(); void update(float t);private: cocos2d::size _cellsize; //the size of cell unsigned char _itemnum; // the number of item};
cell .源文件
//////////////////////////////////////////////////////////////////////////////////////////////***************************customtableviewcell class**************************************/////////////////////////////////////////////////////////////////////////////////////////////xtableviewcell::xtableviewcell():_itemnum(3),_cellsize(size(1920,275)){}xtableviewcell::~xtableviewcell(){}bool xtableviewcell::init(){ if_null_return_false(node::init()); if_null_return_false(initlayout()); //scheduleupdate(); //resumeschedulerandactions(); return true;}bool xtableviewcell::initlayout(){ auto lout = ui::layout::create(); if_null_return_false(lout); lout->setlayouttype(ui::layout::type::absolute); lout->settouchenabled(true); lout->setloopfocus(false); lout->setpassfocustochild(true); lout->setcontentsize(size(_cellsize.width,200.0f)); this->addchild(lout); lout->settag(100); lout->setanchorpoint(vec2::anchor_bottom_left); lout->setposition(vec2(0,75)); for(int j =0;jsetposition(vec2(j*600+90,0)); item->setname(txt); lout->addchild(item,1,j); } return true;}void xtableviewcell::update( float t ){ log(xtableviewcell::update);}bool xtableviewcell::updateitemdata( const unsigned int tag, const std::string icon, const std::string name, const std::string size, const std::string downnum, const std::string score ){ auto lout = this->getchildbytag(100); if_null_return_false(lout); auto item = (griditem*)lout->getchildbytag(tag); if_null_return_false(item); if(!=icon) { item->updateicon(icon); } if(!=name) { item->updatename(name); } if(!=size) { item->updatesize(size); } if(!=downnum) { item->updatedownnum(downnum); } if(!=score) { item->updatescore(score); } return true;}bool xtableviewcell::setitemselected( const unsigned int tag,bool isseleted ){ auto lout = this->getchildbytag(100); if_null_return_false(lout); auto item = (griditem*)lout->getchildbytag(tag); if_null_return_false(item); item->setselected(isseleted); return true;}
里面都实现了什么,其实就是简单的添加了三个自定义item.然后,我们自定义一个tableview实现了两个方法。
一个是去实现滚动到指定cell的方法。
另外一个是我使用触摸的时候需要获得当前使用的cell去判断哪个item位置位于触摸位置。
我们这里只讲键盘的。那么你可能就用不到这个函数了。
代码如下:
class xtableview : public cocos2d::extension::tableview{public: /** * @brief scroll to the designated cell * @param index --- the idx of designated cell **/ void scrolltocellindex(ssize_t index); /*************************************************** * @decripition if you need analyzing touch item , * maby you will use this function to get used cell ****************************************************/ cocos2d::vector getcurrentcells() const;};
//////////////////////////////////////////////////////////////////////////////////////////////***************************xtableview class**************************************/////////////////////////////////////////////////////////////////////////////////////////////void xtableview::scrolltocellindex( ssize_t index ){ this->getcontainer()->stopallactions(); vec2 offset = _offsetfromindex(index)*-1; vec2 maxoffset = this->maxcontaineroffset(); vec2 minoffset = this->mincontaineroffset(); float offx = min(offset.x,maxoffset.x); offx = max(offx,minoffset.x); float offy = min(offset.y,maxoffset.y); offy = max(offy,minoffset.y); this->setcontentoffset(vec2(offx,offy),true);}cocos2d::vector xtableview::getcurrentcells() const{ log(used cell count is %d,_cellsused.size()); return this->_cellsused;}
好了,那么接下来的重点是列表页的实现。
五、页面具体实现由于篇幅受限,代码内容比较多,相信大家自己分析就能理解,那么先就不废话了,先上代码吧。不懂的或者有好的建议希望可以留言讨论。
头文件。(注:具体数据录入,我自己的已删除,需要的可以添加自己的数据,现在展示的基本只是一个界面)
enum class pos_type{ type_0,// right, down and scroll up type_1,//left,right, down and scroll up type_2,//left, down and scroll up type_3,// right,up,down type_4,//left,right,up,down type_5,//left, up,down type_6,// right,up, and scroll down type_7,//left,right,up, and scroll down type_8,//left, up, and scroll down type_9 // can do nothing};enum class change_type{ left, right, up, down, up_scroll, down_scroll, nothing};typedef struct { //item idx ,and start from value 0 to _pagex unsigned char idx; //cell idx unsigned int cellidx; // selected state bool isselected; /***************************************** * pos in screen like a matrix,such as * (0,0),(1,0),(2,0) * (0,1),(1,1),(2,1) * (0,2),(1,2),(2,2) *****************************************/ unsigned char posx; unsigned char posy; pos_type postype;}itemstate;class xgridview :public cocos2d::layer, public cocos2d::extension::tableviewdatasource, public cocos2d::extension::tableviewdelegate{ public: create_func(xgridview); /*** *@brief create a gridview *@ ***/ virtual void scrollviewdidscroll(cocos2d::extension::scrollview* view); virtual void scrollviewdidzoom(cocos2d::extension::scrollview* view); virtual void tablecelltouched(cocos2d::extension::tableview* table, cocos2d::extension::tableviewcell* cell); virtual cocos2d::size tablecellsizeforindex(cocos2d::extension::tableview *table, ssize_t idx); virtual cocos2d::extension::tableviewcell* tablecellatindex(cocos2d::extension::tableview *table, ssize_t idx); virtual ssize_t numberofcellsintableview(cocos2d::extension::tableview *table);cc_constructor_access: xgridview(); virtual ~xgridview(); virtual bool init(); virtual bool initwithdatas(ssize_t celltotalnum,const cocos2d::size tablesize); virtual bool initmovefoucus(); virtual bool inittable(); virtual bool initprogressbar(); virtual bool initkeylisten(); virtual void initstatematrix(); virtual void keyhandler(cocos2d::eventkeyboard::keycode key); virtual bool ontouchbegan(cocos2d::touch *touch, cocos2d::event *unused_event); virtual void ontouchmoved(cocos2d::touch *touch, cocos2d::event *unused_event); virtual void ontouchended(cocos2d::touch *touch, cocos2d::event *unused_event); virtual void ontouchcancelled(cocos2d::touch *touch, cocos2d::event *unused_event); virtual void listenitemtouch(cocos2d::touch *touch, cocos2d::event *unused_event); void updatebysceenstate(); virtual void isitemtouched(cocos2d::node* item,const cocos2d::vec2 point); virtual void decodebyjson(); void update(float t); virtual void onentertransitiondidfinish(); //some model function bool isselectedbyidx(ssize_t midx) const; void updatesceenstatebykey(cocos2d::eventkeyboard::keycode key); pos_type getpostypebyxy(unsigned int x_i,unsigned int y_j); itemstate* getselecteditemstate() const; change_type getchangetype(pos_type postype,cocos2d::eventkeyboard::keycode key); void updatemovefoucs(cocos2d::eventkeyboard::keycode key,pos_type pos); void loadpagenumdata(unsigned int cellindx); void keylistendelay(float t); void updatedalay(float t); void onexit() override; // update cell at idx void updatecellatidx(ssize_t idx); // update item at idx void updateitematidx(ssize_t idx); private: xtableview* _mtable; cocos2d::sprite* _progressbar; ssize_t _celltotalnum; cocos2d::size _tablesize; ssize_t _pagex; ssize_t _pagey; std::vector _iconimg; std::vector _appname; std::vector _appsize; std::vector _downnum; std::vector _appscore; //the state of screen,true means selected and false means unselected std::vector _screenstate; //the cell of selected idx ssize_t _currentcellidx; //item idx which in cell unsigned char _selecteditmidx; bool _isdecoded; unsigned int _itemtotalnum; std::atomic_bool _firstpageupdate[9]; cocos2d::vec2 _pos[9]; cocos2d::sprite* _movefoucus; bool _keycontrl; long _scrolltime; bool _updatecell;};
源文件using_ns_cc;using_ns_cc_ext;char* dataindex[]={ allnum, appico, //app ico image apptitle, //app name downnum, //app down times score , //app score appsize //app size};xgridview::xgridview():_mtable(nullptr),_progressbar(nullptr), _celltotalnum(100),_tablesize(size(1920.0f,960.0f)),_movefoucus(nullptr), _pagex(3),_pagey(3),_gridid(0),_isdecoded(false),_keycontrl(true),_currentcellidx(0), _selecteditmidx(0),_itemtotalnum(300),_loadnum(0),_scrolltime(0l),_updatecell(true){ }xgridview::~xgridview(){ cc_safe_release(_mtable); cc_safe_release(_progressbar);}bool xgridview::init(){ if_return_false(!initwithdatas(_celltotalnum,_tablesize)); return true;}bool xgridview::initwithdatas(ssize_t celltotalnum,const size tablesize ){ if_null_return_false(layer::init()); setdata(_json); _celltotalnum = celltotalnum; _tablesize = tablesize; if_null_return_false(initkeylisten()); if_null_return_false(initmovefoucus()); if_null_return_false(inittable()); if_null_return_false(initprogressbar()); initstatematrix(); decodejsonbyid(); return true;}void xgridview::tablecelltouched(tableview* table,tableviewcell* cell ){ log(cell touched at index: %ld, cell->getidx()); auto lout = (ui::layout*)cell->getchildbytag(100); if_return(!lout); for(auto &item : lout->getchildren()) { if(!item) continue; else { if(item==lout->getcurrentfocusedwidget(true)) { ((griditem*)item)->setselected(true); //_selectedidx = cell->getidx()*_pagex+item->gettag(); } else { ((griditem*)item)->setselected(false); } } }}size xgridview::tablecellsizeforindex(tableview *table, ssize_t idx ){ return size(_tablesize.width, _tablesize.height/_pagey);}tableviewcell* xgridview::tablecellatindex(tableview *table, ssize_t idx ){ auto string = string::createwithformat(%ld, idx); tableviewcell *cell = table->dequeuecell(); if (!cell) { cell = xtableviewcell::create(); if_return_p(!cell,nullptr); cell->autorelease(); return cell; for(unsigned char i=0;i_iconimg.size()-1||itemidx>_appname.size()-1); ((xtableviewcell*)cell)->updateitemdata(i,_iconimg.at(itemidx),_appname.at(itemidx),5.03m,,7.6); ((xtableviewcell*)cell)->setitemselected(i,idx==_currentcellidx&&i==_selecteditmidx); } auto label = label::createwithsystemfont(string->getcstring(), helvetica, 40.0); if_null_return_p(label,cell); label->setposition(vec2::zero); label->setanchorpoint(vec2::zero); label->settag(123); cell->addchild(label); } else { auto _cellchild = cell->getchildbytag(100); for(unsigned char i=0;i_iconimg.size()-1||itemidx>_appname.size()-1); ((xtableviewcell*)cell)->updateitemdata(i,_iconimg.at(itemidx),_appname.at(itemidx),5.03m,,7.6); ((xtableviewcell*)cell)->setitemselected(i,idx==_currentcellidx&&i==_selecteditmidx); } auto label = (label*)cell->getchildbytag(123); if_return_p(!label,cell); label->setstring(string->getcstring()); } return cell;}ssize_t xgridview::numberofcellsintableview(tableview *table ){ return _celltotalnum;}bool xgridview::inittable(){ _mtable = (xtableview*)tableview::create(this,_tablesize); if_return_false(!_mtable); _mtable->setdirection(scrollview::direction::vertical); _mtable->setdelegate(this); this->addchild(_mtable); _mtable->setverticalfillorder(tableview::verticalfillorder::top_down); _mtable->reloaddata(); return true;}void xgridview::scrollviewdidscroll( cocos2d::extension::scrollview* view ){ vec2 pos = view->getcontentoffset(); vec2 _pos = view->getcontentsize()-view->getviewsize(); float percent = -(pos.y/_pos.y); // log(scroll percent is : %f, percent); if_null_return(_progressbar); _progressbar->setpositiony(960/2-600/2 +_progressbar->getscaley()*_progressbar->getcontentsize().height +600*percent*(1-_progressbar->getscaley()));}void xgridview::scrollviewdidzoom( cocos2d::extension::scrollview* view ){}bool xgridview::ontouchbegan( touch *touch, event *unused_event ){ return true;}void xgridview::ontouchmoved( touch *touch, event *unused_event ){}void xgridview::ontouchended( touch *touch, event *unused_event ){ listenitemtouch(touch,unused_event);}void xgridview::ontouchcancelled( touch *touch, event *unused_event ){}void xgridview::listenitemtouch( touch *touch, event *unused_event ){ auto touchpoint = touch->getlocationinview(); touchpoint = director::getinstance()->converttogl(touchpoint); for(auto &e:_mtable->getcurrentcells()) { if_null_continue(e); log(cell[%d],e->getidx()); auto lout = e->getchildbytag(100); if_null_continue(lout); if(dynamic_cast(lout)) { for (auto item:((ui::layout*)lout)->getchildren()) { isitemtouched(item,touchpoint); } } }}void xgridview::isitemtouched( cocos2d::node* item,const cocos2d::vec2 point ){ if_return(!item); auto gitem = dynamic_cast(item); if_return(!gitem); auto acp = gitem->getanchorpoint();//item锚点 auto itempos = gitem->getposition();//item相对父容器的pos itempos = gitem->getparent()->converttoworldspacear(itempos);//相对于世界的位置 auto itemsize = gitem->getcontentsize(); auto itemrect = rect(itempos.x,itempos.y,itemsize.width,itemsize.height); if(itemrect.containspoint(point)) { gitem->setselected(true); //_selectedidx = gitem->getidx(); //log(_selectedidx=%d,_selectedidx); } else { gitem->setselected(false); }}bool xgridview::initprogressbar(){ auto barbg = sprite::create(grid/progress_bg.png); if_null_return_false(barbg); barbg->setanchorpoint(vec2::anchor_bottom_left); barbg->setposition(90+600+600+500+80,960/2-600/2); addchild(barbg); _progressbar = sprite::create(grid/progress_pre.png); if_null_return_false(_progressbar); _progressbar->setanchorpoint(vec2::anchor_top_left); addchild(_progressbar); float scaley = 1; if(_celltotalnum>_pagey) { //float s = _pagey/_celltotalnum; scaley = max(_pagey/(_celltotalnum*1.0f),0.02f); } _progressbar->setscaley(scaley); _progressbar->setposition(90+600+600+500+80,960/2-600/2 +_progressbar->getscaley()*_progressbar->getcontentsize().height +600*1*(1-_progressbar->getscaley())); return true;}bool xgridview::initkeylisten(){ auto listener = eventlistenerkeyboard::create(); if_null_return_false(listener); listener->onkeyreleased = [=](eventkeyboard::keycode key,event* event){ keyhandler(key); }; this->geteventdispatcher()->addeventlistenerwithscenegraphpriority(listener,this); return true;}void xgridview::keyhandler(eventkeyboard::keycode key ){ updatesceenstatebykey(key); updatebysceenstate();}void xgridview::initstatematrix(){ if_noempty_clear(_screenstate); for (unsigned int i = 0; i postype; auto change_type = getchangetype(p,key); updatemovefoucs(key,p); auto maxidx = _screenstate.size(); switch (change_type) { case change_type::left: log(left); _selecteditmidx--; for (unsigned int i = 0;iupdatecellatindex(_currentcellidx); break; case change_type::right: log(right); _selecteditmidx++; for (unsigned int i = 0;iupdatecellatindex(_currentcellidx); break; case change_type::up: log(up); _currentcellidx --; for (unsigned int i = 0;iupdatecellatindex(_currentcellidx+1); _mtable->updatecellatindex(_currentcellidx); break; case change_type::down: log(down); _currentcellidx++; for (unsigned int i = 0;iupdatecellatindex(_currentcellidx-1); _mtable->updatecellatindex(_currentcellidx); break; case change_type::up_scroll: if (!_keycontrl) { return; } if(_keycontrl) { _keycontrl = false; scheduleonce(schedule_selector(xgridview::keylistendelay), 0.05f); } log(up_scroll); _currentcellidx--; for (unsigned int i = 0;iscrolltocellindex(_currentcellidx+2); _mtable->updatecellatindex(_currentcellidx+2); _mtable->updatecellatindex(_currentcellidx+1); _mtable->updatecellatindex(_currentcellidx); return; case change_type::down_scroll: if (!_keycontrl) { return; } if(_keycontrl) { _keycontrl = false; scheduleonce(schedule_selector(xgridview::keylistendelay), 0.05f); } log(down_scroll); _currentcellidx ++; for (unsigned int i = 0;iscrolltocellindex(_currentcellidx); _mtable->updatecellatindex(_currentcellidx-2); _mtable->updatecellatindex(_currentcellidx-1); _mtable->updatecellatindex(_currentcellidx); return; case change_type::nothing: log(nothing); return; default: log(default); return; } //_mtable->reloaddata();}pos_type xgridview::getpostypebyxy( unsigned int x_i,unsigned int y_j ){ // if(0==x_i&&0==y_j) return pos_type::type_0; if(0y_j) return pos_type::type_3; if(0y_j) return pos_type::type_4; if(_pagex-1==x_i&&0y_j) return pos_type::type_5; // if(0==x_i&&_pagey-1==y_j) return pos_type::type_6; if(0reloaddata();}void xgridview::decodejsonbyid(){ // do some thing to initialize data //... _isdecoded = true;}void xgridview::handlervaluechangge(float t){ for (unsigned char i=0;iupdatecellatindex(i/_pagex); } }}void xgridview::update( float t ){ layer::update(t); }void xgridview::onentertransitiondidfinish(){ layer::onentertransitiondidfinish(); scheduleupdate(); schedule(schedule_selector(xgridview::updatedalay),0.2f);}bool xgridview::initmovefoucus(){ _movefoucus = sprite::create(grid/focus.png); if_null_return_false(_movefoucus); addchild(_movefoucus); _movefoucus->setanchorpoint(vec2::anchor_bottom_left); //_movefoucus->setposition(500,500); for (unsigned char i=0;isetposition(_pos[0]); return true;}void xgridview::updatemovefoucs( eventkeyboard::keycode key,pos_type pos ){ int mpos = (int)pos; float time = 0.1f; int nextpos = -1; switch (key) { case eventkeyboard::keycode(key_left): if (mpos%_pagex) { nextpos = mpos - 1; } break; case eventkeyboard::keycode(key_right): if ((mpos+1)%_pagex) { nextpos = mpos + 1; } break; case eventkeyboard::keycode(key_up): if (mpos>_pagex-1) { nextpos = mpos - _pagex; } break; case eventkeyboard::keycode(key_down): if (mposstopallactions(); _movefoucus->runaction(moveto::create(time,_pos[nextpos])); }}void xgridview::loadpagenumdata(unsigned int cellindx){ //load data of cell }void xgridview::keylistendelay( float t ){ _keycontrl = true;}void xgridview::updatedalay( float t ){ if(getcurrentmilliontime()-_scrolltime>500) { loadpagenumdata(_currentcellidx); }}void xgridview::onexit(){ notificationcenter::getinstance()->removeallobservers(this); this->unscheduleallselectors(); layer::onexit();}void xgridview::updatecellatidx( ssize_t idx ){ for (unsigned int i = idx*_pagex;i
http://blog.csdn.net/q229827701/article/details/40619697

其它类似信息

推荐信息