Cocos2d-x 3.0final 终结者系列教程21ScrollView原理与使用

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.0final 终结者系列教程21ScrollView原理与使用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

CCScrollView的滚动是藉助于其内部容器的位置变动来达到的,再加以遮盖/剪切便实现不可见的部分进行隐藏。

藉助于CCScrollView,我们可以实现分页效果,简单的富文本,下拉式按钮等。

创建一个CCScrollView式的滚动视图,首先要创建一个容器,此容器可以必须是Node或其子孙类。如下:

1 @H_403_13@
2 @H_403_13@
3 @H_403_13@
4 @H_403_13@
5 @H_403_13@
6 @H_403_13@
7 @H_403_13@
8 @H_403_13@
9 @H_403_13@
10 @H_403_13@
self.layerContainer=display.newColorLayer(ccc4(10,20,30,10)) @H_403_13@
self.layerContainer:setTouchEnabled( true ) @H_403_13@
self.layerContainer:setPosition(ccp(1,0)) @H_403_13@
self.layerContainer:setTouchSwallowEnabled( false ) @H_403_13@
self.layerContainer:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event) @H_403_13@
return self:onCellCallback(event.name,event.x,event.y) @H_403_13@
end) @H_403_13@
self.widgetContainer=display.newSprite() @H_403_13@
:align(display.LEFT_BOTTOM,0) @H_403_13@
:addTo(self.layerContainer) @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@


我们便创建了一个容器,此容器是一个带有颜色的Layer,并设置了位置以及触摸相关事件,还为其添加了一个孩子节点,并使触摸事件绑定到了onCellCallback方法,此方法并没有做过多的处理,只是简单的记录容器触摸事件的起始和结果,如下:

8 @H_403_13@
functionLLScrollView:onCellCallback(event,x,y) @H_403_13@
if event== "began" then @H_403_13@
self.bolTouchEnd= false @H_403_13@
return true @H_403_13@
elseifevent== "ended" then @H_403_13@
true @H_403_13@
end @H_403_13@
end @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@

这个方法可有可无,但为了实现下面的分页就必不可少了,通过self.bolTouchEnd的标记,在后面的代码中才能知道该何时处理,以及更好对CCScrollView进行滚动操作。下面我们来创建一个CCScrollView,并把刚才创建的Layer添加为其的容器:

10 @H_403_13@
self.scrollView=CCScrollView:create() @H_403_13@
<spanstyle= "white-space:pre" > </span>self.scrollView:setContentSize(CCSizeMake(0,0))--設置內容大小 @H_403_13@
> </span>self.scrollView:setViewSize(CCSizeMake(self.scrollWidth,self.scrollHeight))--設置可見大小 @H_403_13@
> </span>self.scrollView:setPosition(ccp(100,100))--設置位置 @H_403_13@
> </span>self.scrollView:setContainer(self.layerContainer)--設置容器 @H_403_13@
> </span>self.scrollView:setDirection(kCCScrollViewDirectionVertical)--設置滾動方向 @H_403_13@
self.scrollView:setClippingToBounds( )--設置剪切 @H_403_13@
self.scrollView:setBounceable( )--設置彈性效果 @H_403_13@
self.scrollView:setDelegate( this )--註冊為自身 @H_403_13@
self:addChild(self.scrollView) @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@

通过setContentSize制定CCScrollView的大小,当然这是可有可无的,其实并不是指定CCScrollView的大小,而是指定其容器的大小,一般我们都会在给容器添加数据的时候,再调整容器的大小;设置视图的可见范围就必不可少了,setViewSize方法为我们提供了设置视图大小,设置视图大小便指定了可见范围,setClippingToBounds方法设置剪切,如果不设置,可见范围的设置便成了虚设,通过setBounceable方法指定视图滚动过程中是否能够滚动,为了让CCScrollView显得不那么僵硬,一般会设置为true;同时我们要设置滚动的方向setDirection,有3个方向,水平、竖直、双向,setDelegate(this)指定注册为自身。通过以上代码我们便创建了一个完整的CCScrollView。

为了实现滚动,还要为其添加滚动监听事件,也就是写个方法把其绑定到CCScrollView的滚动事件上,例如:

1 @H_403_13@
self.scrollView:registerScriptHandler(scrollView2DidScroll,CCScrollView.kScrollViewScroll) @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@

这一行代码就把方法scrollView2DidScroll绑定到了CCScrollView.kScrollViewScroll事件上,要做什么处理工作便在scrollView2DidScroll方法添加,比如我们要实现分页,或滚动时实现一个item的滚动,如下:

10 @H_403_13@
11 @H_403_13@
12 @H_403_13@
13 @H_403_13@
14 @H_403_13@
15 @H_403_13@
16 @H_403_13@
17 @H_403_13@
18 @H_403_13@
19 @H_403_13@
20 @H_403_13@
localfunctionscrollView2DidScroll() @H_403_13@
self.bolTouchEnd== localoffy=self.layerContainer:getPositionY() @H_403_13@
localminy=self.scrollHeight-self.cellNums*self.cellHeight @H_403_13@
offy<0andoffy>minythen @H_403_13@
localitem=-(math. abs (offy)%self.cellHeight) @H_403_13@
item<=-self.cellHeight/2then @H_403_13@
offy<self.preOffythen @H_403_13@
item=offy-item-self.cellHeight @H_403_13@
else @H_403_13@
item=offy-item-self.cellHeight @H_403_13@
end @H_403_13@
else @H_403_13@
item=offy-item @H_403_13@
end @H_403_13@
self.scrollView:setContentOffset(ccp(1,item), ) @H_403_13@
end @H_403_13@
end @H_403_13@
顺便提一下,一些全局变量的定义在这里:

5 @H_403_13@
self.scrollTop=208 @H_403_13@
self.scrollHeight=208 @H_403_13@
self.scrollWidth=152 @H_403_13@
self.cellHeight=52 @H_403_13@
self.cellNums=2 @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@

至于什么意思,看到命名字段应该还是浅显易懂的,就不一一解释了,其中self.preOffy是记录上一次CCScrollView的偏移量。分页也很简单,首先假定我们的ScrollView的偏移量都是负值,确实也是负值。由于CCScrollView会自动纠正第一项和最后一项的位置,所以在第一项和最后一项时我们不做处理,让CCScrollView的内部方法去实现。如果CCScrollView的偏移量对一个item取余数,如果余数大于item的一半我们就分页,否则就归位。代码if offy < self.preOffy then是为了判定滚动方向是上还是下(我的这个CCScrollView的设置方向是竖直的),好了到此为止我们的完整的带分页的CCScrollView就实现了。

现在要对其添加数据,方便起见我又创建了一个类名称为LLScrollItem,实现一个item的类,并为其添加了一个ON_TOUCH_EVENT的事件,完整代码如下:

20 @H_403_13@
21 @H_403_13@
22 @H_403_13@
23 @H_403_13@
24 @H_403_13@
25 @H_403_13@
26 @H_403_13@ @H_902_403@ 27 @H_403_13@
28 @H_403_13@
29 @H_403_13@
30 @H_403_13@
31 @H_403_13@
32 @H_403_13@
33 @H_403_13@
34 @H_403_13@
35 @H_403_13@
36 @H_403_13@
37 @H_403_13@
38 @H_403_13@
39 @H_403_13@
40 @H_403_13@
localLLScrollItem= class ( "LLScrollItem" ,function() @H_403_13@
display.newNode() @H_403_13@
end) @H_403_13@
LLScrollItem.ON_TOUCH_EVENT= "on_touch_event" @H_403_13@
functionLLScrollItem:ctor(params) @H_403_13@
cc(self):addComponent( "components.behavior.EventProtocol" ):exportMethods() @H_403_13@
self.text=params.text @H_403_13@
locallabel=ui.newTTFLabel({ @H_403_13@
text=params.text, @H_403_13@
font= "Arial" 403_13@
size=20, @H_403_13@
}) @H_403_13@
label:setTouchEnabled( ) @H_403_13@
label:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event) @H_403_13@
self:onTouch(event) @H_403_13@
end) @H_403_13@
localrect={ @H_403_13@
{0,0}, @H_403_13@
{150, @H_403_13@
403_13@
403_13@
403_13@
} @H_403_13@
localr,g,b,s=math.random(0,255),math.random(0,255) @H_403_13@
locallayerColor=display.newColorLayer(ccc4(r,s)):addTo(self) @H_403_13@
403_13@
layerColor:setContentSize(CCSizeMake(150,52)) @H_403_13@
localpolygon=display.newPolygon(rect,1):addTo(layerColor) @H_403_13@
403_13@
polygon:setLineWidth(1) @H_403_13@
polygon:setLineColor(ccc4f(255,255)) @H_403_13@
label:addTo(polygon) @H_403_13@
label:align(display.CENTER,75,26) @H_403_13@
label:setColor(ccc3(255-r,255-g,255-b)) @H_403_13@
end @H_403_13@
functionLLScrollItem:onTouch(event) @H_403_13@
self:dispatchEvent({name=LLScrollItem.ON_TOUCH_EVENT,text=self.text}) @H_403_13@
end @H_403_13@
@H_403_13@
LLScrollItem @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@

每一个item是一个有范围界定有色层,并用一个Box包裹,并添加了一个独一的文本,用来以后区别我们点击了哪个item。

利用上面的item类我们就可以为CCScrollView添加数据了:

10 @H_403_13@
for i=1,self.cellNums do @H_403_13@
self.scrollTop=self.scrollTop-self.cellHeight @H_403_13@
localcell=LLScrollItem. new ({text= "ScrollItem:" ..i}):addTo(self.widgetContainer) @H_403_13@
403_13@
@H_403_13@
cc.EventProxy. (cell,cell) @H_403_13@
:addEventListener(cell.ON_TOUCH_EVENT,function(event) @H_403_13@
self.label:setString(event.text) @H_403_13@
end) @H_403_13@
因为容器内容变化了,所以要改变其大小,以便能够完全承载所有数据;设置容器的位置是容器能够达到的最低点,容器的孩子self.widgetContainer,其实是一个真正的承载数据的节点,我们在这里要设置其能够达到的最高高度。

我们之所以要给容器添加一个子节点,并所有数据都添加到其子节点上,是为应对动态增删其数据内容的情况,并使CCScrollView的显示正常。

我们再创建两个控件,一个Label一个Button:

self.label=ui.newTTFLabel({ @H_403_13@
text= "Hello,World" 403_13@
403_13@
color=ccc3(163,140,14), @H_403_13@
align=ui.TEXT_ALIGN_CENTER @H_403_13@
}) @H_403_13@
:pos(display.cx+100,display.cy+100) @H_403_13@
:addTo(self) @H_403_13@
self.button=cc.ui.UIPushButton. ({ @H_403_13@
disabled= "nil" normal= "res/GreenScale9Block.png" pressed= "res/PinkScale9Block.png" 403_13@
}) @H_403_13@
:align(display.CENTER,display.cx+100,display.cy-100) @H_403_13@
:addTo(self) @H_403_13@
:onButtonClicked( @H_403_13@
function() @H_403_13@
self:addItem() @H_403_13@
end @H_403_13@
) @H_403_13@ @H_403_13@
@H_403_13@ @H_403_13@

这个Label就是上面所说的self.label,此Button是为了实现动态添加数据的功能,点击Button就为CCScrollView添加数据,我们把其相应事件绑定到了addItem方法,此方法实现为:

23 @H_403_13@
functionLLScrollView:addItem() @H_403_13@
self.cellNums=self.cellNums+1 @H_403_13@
..self.cellNums}):addTo(self.widgetContainer) @H_403_13@
403_13@
@H_403_13@
403_13@
403_13@
self.label:setString(event.text) @H_403_13@
end) @H_403_13@
@H_403_13@
localh=self.cellNums*self.cellHeight @H_403_13@
h<self.scrollHeightthen @H_403_13@
h=self.scrollHeight @H_403_13@
end @H_403_13@
self.layerContainer:setContentSize(CCSizeMake(self.scrollWidth,h)) @H_403_13@
self.widgetContainer:setPositionY(h-self.scrollHeight) @H_403_13@
self.layerContainer:setPositionY(self.scrollHeight-h) @H_403_13@
self.preOffy=self.layerContainer:getPositionY() @H_403_13@
localh1=self.scrollHeight-h @H_403_13@
h1<0thenh1=0end @H_403_13@
self.layerContainer:setPositionY(h1) @H_403_13@
同样的,在添加完数据之后,一定要调整容器及其子节点的位置及大小,否则显示出问题。到此位置我们已经实现了一个完整的能够实现分页、动态添加数据的CCScrollView,至于动态删除,仿照动态添加自然也就出来了。

猜你在找的Cocos2d-x相关文章