The actual content size of UIListView in cocos2d-x

Source: Internet
Author: User

The actual content size of UIListView in cocos2d-x

In actual projects, UIListView is often used in the UI interface, and most of them are directly added to CocoStudio. However, some pitfalls and lack of functions were found during use. Then, we looked at the underlying logic and found that a slight change to the underlying level could meet the requirements, therefore, we will analyze the underlying layer of UIListView based on requirements and make some changes at the same time.

  Requirement: dynamically adjust the size of the listView Based on the content in the linked list.First, we need to know how to insert and remove an item in the linked list and the listView itself will handle it:

 

Void ListView: pushBackDefaultItem () {if (! _ Model) {return;}/* clone a template and add it to the array of items */Widget * newItem = _ model-> clone (); _ items-> addObject (newItem);/* adjust the layout of the new item based on the Basic settings of listView */remedyLayoutParameter (newItem); addChild (newItem);/* emphasis: turn on the refresh switch */_ refreshViewDirty = true ;}

 

The last sentence here is the focus. Only a refresh will calculate the new display, and the previous changes will take effect. So when we add an item, in fact, the current frame is not refreshed immediately. If the size is obtained at this time, it will be the same as the previous one and has not changed. So we need to know when the switch _ refreshViewDirty will take effect, as follows:

 

Void ListView: sortAllChildren () {ScrollView: sortAllChildren (); if (_ refreshViewDirty) {/* refresh */refreshView (); _ refreshViewDirty = false ;}}
Void ListView: refreshView () {ccArray * arrayItems = getItems ()-> data; int length = arrayItems-> num; for (int I = 0; I
 
  
(ArrayItems-> arr [I]); item-> setZOrder (I); remedyLayoutParameter (item);}/* update content size */updateInnerContainerSize ();}
 

We can see that the most critical function to change the size is updateInnerContainerSize ():

Define a variable to save the actual size. The reason is that the calculation result of the listView is not based on the content, but the size set by the user at first, the actual size will be discarded, so we need to save her:

 

CCSize _actualInnerSize;
Void ListView: updateInnerContainerSize () {switch (_ direction) {case SCROLLVIEW_DIR_VERTICAL :{/*... * // * Save the actual size */_ actualInnerSize = CCSize (finalWidth, finalHeight); setInnerContainerSize (_ actualInnerSize); break;} case SCROLLVIEW_DIR_HORIZONTAL :{/*... * // * Save the actual size */_ actualInnerSize = CCSize (finalWidth, finalHeight); setInnerContainerSize (_ actualInnerSize); break;} default: break ;}}

 

 

SetInnerContainerSize (_ actualInnerSize); this function is defined in the parent class:

 

Void ScrollView: setInnerContainerSize (const CCSize & size) {/* Get the size set by the user (default if not set) */float innerSizeWidth = _ size. width; float innerSizeHeight = _ size. height;/* get the original size */CCSize originalInnerSize = _ innerContainer-> getSize ();/* compare the size of the updated content with the SET size */if (size. width <_ size. width) {/* If the size of the new content is smaller than the value set, a prompt is output, and the size of the new content prevails, the size does not change */CCLOG ("Inner width <= scrollview width, it will be force sized! ");} Else {/* If the size of the new content is greater than the value set, the new content size prevails */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 ));}

In the updateInnerContainerSize function, we save the actual content size. We need to write a get function to get the content:

 

 

CCSize ListView: getActualInnerSize () {/* Key: refresh the current frame immediately, update the size */refreshView (); return _ actualInnerSize ;}

 

Final Implementation requirement: listView-> setSize (getActualInnerSize ())

 

The above is the UIListView control added in CocoStudio. If it is manually created, there are three points to note:

 

To be able to scroll, two conditions must be implemented

①: SetTouchEnable (true)

②: Make sure to put UIListView into UILayer. Only UILayer can listen to the UI touch series, and CCLayer cannot.

Therefore, you need to create a UILayer * layer; layer-> addWidget (list); // It Must Be addWidget, indicating to be added as a pendant. addChild is not allowed, and addChild (layer) is added );

③: When a control is added to the list, the position is automatically arranged in the list, which is not manually managed (and the position is usually incorrect. The center is in the upper left corner and cannot be changed, to adjust the location, you can only add the middle layer, such as UILayout. Note that UILayout is equivalent to a layer, and coordinate calculation is the same as that of a layer.

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.