cocos2d-x改底层之获取UIListView的实际内容大小

实际项目中UI界面中经常会用到UIListView,大多会在CocoStudio中直接添加这个控件。但是在使用中发现了一些坑和功能缺乏,然 后就看了一下底层的逻辑,发现稍微改一下底层就可以满足需求,所以下面就针对需求来分析UIListView的底层,同时做一些改动。

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

首先,我们要知道,我们插入和移除链表中的一项,listView本身会如何处理:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

void ListView::pushBackDefaultItem()

{

    if (!_model)

    {

        return;

    }

    /* 克隆一份模板,并添加到项的数组里 */

    Widget* newItem = _model->clone();

    _items->addObject(newItem);

    /* 根据listView的基础设置来调整新加项的布局关系 */

    remedyLayoutParameter(newItem);

    addChild(newItem);

    /* 重点:打开刷新开关 */

    _refreshViewDirty = true;

}

这里最后一句才是重点,只有刷新了才会真正计算新的显示,之前的改动才真正生效,所以放我们添加一项的时候,当前帧其实并没有立即刷新,如果这时候 获取大小,只会和之前的一样,并没有改变,那么我们要知道,开关_refreshViewDirty是在什么时候起作用了呢,如下:

?


1

2

3

4

5

6

7

8

9

10

void ListView::sortAllChildren()

{

    ScrollView::sortAllChildren();

    if (_refreshViewDirty)

    {

        /* 刷新 */

        refreshView();

        _refreshViewDirty = false;

    }

}

?


1

2

3

4

5

6

7

8

9

10

11

void ListView::refreshView()

{

    ccArray* arrayItems = getItems()->data;

    int length = arrayItems->num;

    for (int i=0; i<length; item="static_cast<Widget*">(arrayItems->arr[i]);

        item->setZOrder(i);

        remedyLayoutParameter(item);

    }

    /* 更新内容大小 */

    updateInnerContainerSize();

}</length;>

可以看到,最关键的改变大小的函数updateInnerContainerSize():

定义一个变量用来保存真实大小,原因是listView本身计算大小的结果并不是以内容为准,而是以最初用户设置的大小,那么真实的大小会被遗弃,所以我们要保存住她:

?


1

CCSize _actualInnerSize;

?


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

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);这个函数是在父类定义的:


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

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函数来获取:

?


1

2

3

4

5

6

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要注意的是,它相当于一个层,坐标计算和层一样。

时间: 2024-12-24 19:39:30

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

python3获取一个网页特定内容

我们今天要爬取的网址为:https://www.zhiliti.com.cn/html/luoji/list7_1.html 一.目标:获取下图红色部分内容 即获取所有的题目以及答案. 二.实现步骤. 分析:1,首先查看该网站的结构. 分析网页后可以得到: 我们需要的内容是在该网页<li>标签下,详细内容链接在<small>的<a>的href中. 但是这样我们最多只能获取这一页的内容 别着急 我们点击第二页看一下目标网址有什么变化 我们发现目标网址最后的数字变成了2 再

java 如何获取网页的动态内容,并解析网页内容

(笔记) 获取网页的动态内容参考 https://pastebin.com/raw/FePkm2kp Maven: <!--获取网页源码,包括动态内容--><dependency> <groupId>htmlunit</groupId> <artifactId>htmlunit</artifactId> <version>1.14</version></dependency> 实现: WebClie

获取要下载文件的大小信息

原文来自IOS教程网,转载时请注明文章的来源:http://ios.662p.com/thread-1660-1-1.html NSURLConnectionDataDelegate方法中有: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {     //This method is calle

【JSP EL】EL表达式 获取list长度/不用循环,EL在List中直接获取第一项的内容/EL获取Map的键,Map的值

1.EL表达式 获取list长度 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <c:if test="${fn:length(list名字)>1}"&g

c++: 获取delete[]中的数组大小

看一个小例子: 1 #include <iostream> 2   3 using namespace std; 4   5 class A { 6 public: 7     A() { cout << "A::A()" << endl; } 8     ~A() { cout << "A::~A()" << endl; } 9 }; 10   11 int main() { 12     A* a =

WPF Paragraph获取或修改文本内容

一.说明 Paragraph继承自Block,Block继承自TextElement,在TextElement中 // // 摘要: // 获取表示元素中内容末尾的 System.Windows.Documents.TextPointer. // // 返回结果: // 表示 System.Windows.Documents.TextElement 中内容末尾的 System.Windows.Documents.TextPointer. public TextPointer ContentEnd

封装函数getClient获取当前显示区域的大小,即clientWidth和clientHeight

1 //获取当前显示区域的大小,即clientWidth和clientHeight 2 function getClient(){ 3 var isXHTML; //初始值默认 符合DOM的xHTML标准 4 var clientWidth,clientHeight; 5 if(document.documentElement.clientWidth = null || document.documentElement.clientWidth <=0){ 6 if(document.body.c

【实例】正则表达式利用grep和sed处理日志内容,获取所需的内容

[实例]正则表达式利用grep和sed处理日志内容, 获取所需的内容 app.log文件内容: 2014-09-11 00:00:01,516 INFO [com.tt.bb.thread.Control] - Socket连接:/182.105.83.33:532172014-09-12 10:00:06,555 INFO [com.tt.bb.thread.Control] - Socket连接:/182.113.83.51:53249 2014-09-13 20:00:11,587 INF

C#获取文件夹/文件的大小以及占用空间 转摘自:http://www.cnblogs.com/chenpeng-dota/articles/2176470.html

C#获取文件夹/文件的大小以及占用空间 今天,头给了个任务:写个方法,我会给你个路径,计算这个路径所占用的磁盘空间 . 然后,找了很多资料.但大部分都是获取文件夹/文件的大小的.对于占用空间的没有成品代码.(ps:我没找到.)后来,在网上找了些资料,自己捣鼓出来了.在这里记录下,一则说不定以后能用到.再则如果有高手有更好的方法或者建议,求指点. 废话不多说了.begin. 首先说下文件夹/文件大小与占用空间的区别. 这个是硬盘分区格式有关 大小是文件的实际大小,而占用空间是占硬盘的实际空间 以F