cocos2d-x改底层之获取UIListView的实际内容大小
来源:互联网 发布:诺基亚rm1013下载软件 编辑:程序博客网 时间:2024/05/29 08:18
实际项目中UI界面中经常会用到UIListView,大多会在CocoStudio中直接添加这个控件。但是在使用中发现了一些坑和功能缺乏,然后就看了一下底层的逻辑,发现稍微改一下底层就可以满足需求,所以下面就针对需求来分析UIListView的底层,同时做一些改动。
需求:根据链表中的内容来动态调整listView本身的大小
void ListView::pushBackDefaultItem(){ if (!_model) { return; } /* 克隆一份模板,并添加到项的数组里 */ Widget* newItem = _model->clone(); _items->addObject(newItem); /* 根据listView的基础设置来调整新加项的布局关系 */ remedyLayoutParameter(newItem); addChild(newItem); /* 重点:打开刷新开关 */ _refreshViewDirty = true;}
这里最后一句才是重点,只有刷新了才会真正计算新的显示,之前的改动才真正生效,所以放我们添加一项的时候,当前帧其实并没有立即刷新,如果这时候获取大小,只会和之前的一样,并没有改变,那么我们要知道,开关_refreshViewDirty是在什么时候起作用了呢,如下:
void ListView::sortAllChildren(){ ScrollView::sortAllChildren(); if (_refreshViewDirty) { /* 刷新 */ refreshView(); _refreshViewDirty = false; }}
void ListView::refreshView(){ ccArray* arrayItems = getItems()->data; int length = arrayItems->num; for (int i=0; i<length; i++) { Widget* item = static_cast<Widget*>(arrayItems->arr[i]); item->setZOrder(i); remedyLayoutParameter(item); } /* 更新内容大小 */ updateInnerContainerSize();}
可以看到,最关键的改变大小的函数updateInnerContainerSize():
定义一个变量用来保存真实大小,原因是listView本身计算大小的结果并不是以内容为准,而是以最初用户设置的大小,那么真实的大小会被遗弃,所以我们要保存住她:
CCSize _actualInnerSize;
void ListView::updateInnerContainerSize(){ switch (_direction) { case SCROLLVIEW_DIR_VERTICAL: { /*...*/ /* 保存真实大小 */ _actualInnerSize = CCSize(finalWidth, finalHeight); setInnerContainerSize(_actualInnerSize); break; } case SCROLLVIEW_DIR_HORIZONTAL: { /*...*/ /* 保存真实大小 */ _actualInnerSize = CCSize(finalWidth, finalHeight); setInnerContainerSize(_actualInnerSize); break; } default: break; }}
void ScrollView::setInnerContainerSize(const CCSize &size){ /* 获取用户设置的大小(没设置就是默认的) */ float innerSizeWidth = _size.width; float innerSizeHeight = _size.height; /* 获取原始大小 */ CCSize originalInnerSize = _innerContainer->getSize(); /* 更新后的新的内容大小与设置的大小作比较 */ if (size.width < _size.width) { /* 如果新的内容大小比设置的要小,输出提示,并以设置的大小为准,大小不改变 */ CCLOG("Inner width <= scrollview width, it will be force sized!"); } else { /* 如果新的内容大小比设置的要大,则以新内容大小为准 */ innerSizeWidth = size.width; } if (size.height < _size.height) { CCLOG("Inner height <= scrollview height, it will be force sized!"); } else { innerSizeHeight = size.height; } _innerContainer->setSize(CCSize(innerSizeWidth+5, innerSizeHeight+10));}
在updateInnerContainerSize函数中我们以保存了实际内容大小,需要写一个get函数来获取:
CCSize ListView::getActualInnerSize(){ /* 重点:立即(当前帧)执行刷新,更新大小 */refreshView(); return _actualInnerSize;}
最后实现需求:listView->setSize(getActualInnerSize())
为了能够滚动,要实现两个条件
①:setTouchEnable(true)
②:一定要将UIListView 放入到UILayer中,只有UILayer才会监听UI系列触摸,CCLayer不可以
所以需要创建一个UILayer* layer;layer->addWidget(list);//一定是addWidget,表示以挂件形式添加,addChild不可以,最后再addChild(layer);
③:向列表中添加控件时,列表会自动排好位置,此时位置是不受手动管理的(而且位置通常不对,中心点在左上角,我们无法改变,做相对偏移等);但有时候我们为了调整位置,只能添加中间层,如UILayout,而UILayout要注意的是,它相当于一个层,坐标计算和层一样。
- cocos2d-x改底层之获取UIListView的实际内容大小
- cocos2d-x改底层之动态改变UIListView中的某项在链表中的位置
- cocos2d-x改底层之RichText富文本换行
- cocos2d-x 获取屏幕大小 实际设计大小 分辨率适配问题
- cocos2d-X 节点(UIListView.h)API
- cocos2d-x中的获取屏幕、节点的大小问题
- Cocos2d-x与OpenGL底层的感想
- Cocos2d-x与OpenGL底层的感想
- Cocos2d-X游戏开发之Sprite纹理的大小限制
- 获取传递过来指针的实际大小
- 动态获取应用的视图实际大小
- 动态获取应用的视图实际大小
- Android获取屏幕的实际大小
- 精通cocos2d-x必须要学习的内容 -沈大海cocos2d-x教程之4
- 获取图片实际大小
- cocos2d-x 3.x的底层渲染机制
- 获取文件内容的大小
- cocos2d-x 之如何获取圆的轨迹路线
- 分享VC++中传统控件的控件通知消息
- 【BFS模板】HDU1253 胜利大逃亡
- pcap文件解析--pcap文件头与包文件头(一)
- cygwin安装、卸载及一些问题解决
- 信息与熵的计算
- cocos2d-x改底层之获取UIListView的实际内容大小
- Java流程控制语句
- clistctrl改变单元格的背景颜色
- 排序算法的java实现
- 手把手教你把Vim改装成一个IDE编程环境(图文)
- 在来比较一下Java和C++的一些重要特征
- HDU 1358 Period(KMP)
- mysql安装图解 mysql图文安装教程(详细说明)
- 字符集与编码格式