listview的pushBackDefaultItem中的item属性被修改问题

time:2015/05/04

1. 描述

  在cocostudio中有两个控件,一个listview,另外一个是隐藏的imageview,其中后者作为listview的元素。每次使用的时候把ImageView设置为默认的item(setItemModel),然后通过listview:pushBackDefaultItem进行插入指定个数的元素。但是在使用过程中会修改listview中的元素(通过getItem得到其中的元素),结果修改了listview的元素之后作为默认itemmodel的ImageView的属性也被修改了。eg:ImageView下面有一个node也是ImageView,一直都是可见的,但是修改完之后也会变成不可见的

2.原因

(1)分析

* 查看自己的代码setItemModel和pushBackDefaultItem两个接口的源码表示每次都是clone一个新的控件出来,所以getItem不会拿到作为itemmodel的控件并且修改其属性的

* 再看自己使用的代码:每次的ItemModel都是通过seekWidgetByName得到的

* 综合前面两点,很有可能就是seekWidgetByName的时候得到的item控件并不是UI界面上的那个,而是clone出来的,因为tag和name完全一样

Widget* Widget::clone()
{
    Widget* clonedWidget = createCloneInstance();
    clonedWidget->copyProperties(this);
    clonedWidget->copyClonedWidgetChildren(this);
    return clonedWidget;
}


(2)验证

* 比较每次seekWidgetByName出来的item,都是false,这说明的确不一样

* 修改获取item的方式,第一次读取UI界面的时候保存为全局的,每次就直接使用,比较每次的结果都是true(变量一样,当然都是一样的)

3.解决

(1)第一次加载UI界面(json)文件的时候把需要用到的控件保存下来(这里就是这个listview要用到的item),不要每次都通过seekWidgetByName去查找

4. 总结

(1)listview的pushBackDefaultItem是每次clone一个新的控件的,但是会把所有的属性复制过去,包括唯一标识一个控件的name和tag

(2)seekWidgetByName是根据名字或者tag进行深度优先遍历(其实是中序遍历),但是如果有相同的名字的控件就会出现问题,找到第一个相同名字的就直接返回了

(3)一个UI界面第一次加载的时候用seekWidgetByName找到后面要用的控件,以后不要通过这种方式去查找了,不但效率上有影响,而且还会出现问题

原文地址:https://www.cnblogs.com/pk-run/p/4475605.html