实际项目中UI界面中常常会用到UIListView。大多会在CocoStudio中直接加入这个控件。

可是在使用中发现了一些坑和功能缺乏,然后就看了一下底层的逻辑,发现略微改一下底层就能够满足需求,所以以下就针对需求来分析UIListView的底层。同一时候做一些修改。



需求:依据链表中的内容来动态调整listView本身的大小

首先,我们要知道。我们插入和移除链表中的一项,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;
}
}

setInnerContainerSize(_actualInnerSize);这个函数是在父类定义的:

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())

上面是在CocoStudio中加入的UIListView控件,假设是手动创建的话有三点注意:

为了可以滚动,要实现两个条件

①:setTouchEnable(true)

②:一定要将UIListView 放入到UILayer中,仅仅有UILayer才会监听UI系列触摸。CCLayer不能够

所以须要创建一个UILayer* layer;layer->addWidget(list);//一定是addWidget。表示以挂件形式加入,addChild不能够。最后再addChild(layer)。

③:向列表中加入控件时,列表会自己主动排好位置,此时位置是不受手动管理的(并且位置通常不正确,中心点在左上角,我们无法改变,做相对偏移等);但有时候我们为了调整位置,仅仅能加入中间层。如UILayout。而UILayout要注意的是,它相当于一个层,坐标计算和层一样。

cocos2d-x改底层之获取UIListView的实际内容大小的更多相关文章

  1. java中CRUD(增删查改)底层代码的实现

    java中CRUD(增删查改)底层代码的实现: package com.station.dao; import com.station.model.Product; import java.sql.* ...

  2. python3获取一个网页特定内容

    我们今天要爬取的网址为:https://www.zhiliti.com.cn/html/luoji/list7_1.html 一.目标:获取下图红色部分内容 即获取所有的题目以及答案. 二.实现步骤. ...

  3. 转 使用utl_http获取某个http页面内容

    #########1.ACL详细解释: 11g 对于XDB  UTL_HTTP or others package 的权限管控进一步加强,如果需要使用到XDB 以下包 UTL_TCP, UTL_SMT ...

  4. 织梦DEDECMS {dede:arclist},{dede:list}获取附加表字段内容

    以前用织梦DEDECMS做二次开发时获取附加表字段内容都是通过runphp执行SQL查询获得,最近看了看手册,发现一个非常简便的方法. 用arclist调用于附加表字段的方法: 方法一: 要获取附加表 ...

  5. Shell 获取指定行的内容

    需求: 有一个文件,根据指定的字符串,得到该字符串上两行的内容. 文件内容如下: linux-56:# cat sys.ttconnect.ini # Copyright (C) 1999, 2006 ...

  6. jquery获取文本框的内容

    使用jquery获取文本框的内容有以下几种: 1.根据ID取值(id属性): // javascript <script type="text/javascript"> ...

  7. Android中获取应用程序(包)的大小-----PackageManager的使用(二)

    通过第一部分<<Android中获取应用程序(包)的信息-----PackageManager的使用(一)>>的介绍,对PackageManager以及 AndroidMani ...

  8. PHP高效获取远程图片尺寸和大小(转)

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  9. Android 获取系统短信内容

    //这里通过内容提供者获取系统短信内容 Uri uri = Uri.parse("content://sms/"); String[] projection = {"_i ...

随机推荐

  1. cvs 文件无法上传debug

    当时文件始终上传不成功时(一般先update后commit): cvs update filename report:move away filename ,it is in the way cvs ...

  2. linux系统,python3.7环境安装talib过程

    获取源码wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz 解压进入目录tar -zxvf ta-lib-0. ...

  3. spring mvc3 配置<mvc:resources/> @Controller失效

    因为配置了:<mvc:resources  location=" "  mapping=""  /> ,@Controller失效访问404 这里还 ...

  4. iOS-MVC设计模式不足

    View 的最大的任务就是向 Controller 传递用户动作事件. ViewController 不再承担一切代理和数据源的职责,通常只负责一些分发和取消网络请求以及一些其他的任务. 1.1 苹果 ...

  5. 大数据学习——azkaban工作流调度系统

    azkaban的安装部署 在/root/apps 1目录下新建azkaban文件夹 上传安装包到azkaban 2解压 .tar.gz 3删掉安装包 [root@mini1 azkaban]# .ta ...

  6. SQL server 数据库备份至服务器本地磁盘和其他服务器磁盘

    前言 因工作需要将数据库每日备份至服务器本地磁盘和其他服务器磁盘,对网上的例子进行改造,解决了SQL server数据库备份的问题. 一.将指定数据库备份到本地 将数据库affair_stydy全备份 ...

  7. 2017ACM/ICPC广西邀请赛-重现赛(感谢广西大学)

    上一场CF打到心态爆炸,这几天也没啥想干的 A Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

  8. ffmpeg常见名词解析

    scan_all_pmts, 扫描全部的ts流的"Program Map Table"表.

  9. HDU 4417 Super Mario(划分树问题求不大于k的数有多少)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. 彻底解决Request Too Long的问题

    运行regedit,进入 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters , 1. 添加类型为 DWORD(3 ...