本来是在紧急开发中,想找官方已经有的,但是官方好像没有,无奈,只能自己写了。
目前只写到了可以循环使用,也可以到顶不动,但是那个回弹效果还没写完。
第一个坑:找监听。
百度上面说是有几种办法,我都试了。第一感觉就是没用,然后不断的尝试找资料,后来发现是因为点击事件的原因,我ScrollView 的底图是一个layout,打开layout点击事件后就收不到全局点击事件了,所以需要关闭点击事件。
self.image = ccui.Layout:create()
self.image:ignoreContentAdaptWithSize(false)
self.image:setName("Layout")
self.image:setContentSize(self.startX * 2, self.scrollViewHeight)
self.image:setPosition(self.x , self.y)
self.image:setAnchorPoint(0.5,0.5)
self.image:setOpacity(0)
self.image:setClippingEnabled(true)
self:addChild(self.image) 其他的监听都没返回touch坐标,所以不行
第二个坑:额,暂时没啥坑。先不写。下面贴代码:
local M = class("ScrollView1" , cc.Node)
local Utils = require("Utils")
function M:ctor(par)
if par then
self.scrollView = par.scrollView
self.gapY = par.gapY
self.scrollViewHeight = par.scrollViewHeight
self.startX = par.startX
self.object = par.object
self.x = par.x or 500
self.y = par.y or 500
if par.maxShowView then
self.maxShowView = par.maxShowView
else
self.maxShowView = 10
end
self.isQidong = false
end
self.objectList = {}
self.objectViewList = {}
self.image = ccui.Layout:create()
self.image:ignoreContentAdaptWithSize(false)
self.image:setName("Layout")
self.image:setContentSize(self.startX * 2, self.scrollViewHeight)
self.image:setPosition(self.x , self.y)
self.image:setAnchorPoint(0.5,0.5)
self.image:setOpacity(0)
self.image:setClippingEnabled(true)
self:addChild(self.image)
self:TouchEvent()
end
function M:ValueMoveUp()
-- 当倒数第二个元素高于限制的高度时,便需要将第一个元素放到最后面
local temp = self.objectList[self.maxShowView - 1]
if temp:getPositionY() > self.y - self.scrollViewHeight/2 then
if self.par[self.maxIndex + 1] then
local maxPositionX = self.objectList[self.maxShowView]:getPositionX()
local maxPositionY = self.objectList[self.maxShowView]:getPositionY() - self.gapY
local tempValue = table.remove(self.objectList , 1)
self.maxIndex = self.maxIndex + 1
self.minIndex = self.minIndex + 1
tempValue:setPosition(maxPositionX , maxPositionY)
tempValue:Update(self.par[self.maxIndex])
table.insert(self.objectList , tempValue)
else
local maxPositionX = self.objectList[self.maxShowView]:getPositionX()
local maxPositionY = self.objectList[self.maxShowView]:getPositionY() - self.gapY
local tempValue = table.remove(self.objectList , 1)
self.maxIndex = 1
self.minIndex = self.minIndex + 1
tempValue:setPosition(maxPositionX , maxPositionY)
tempValue:Update(self.par[self.maxIndex])
table.insert(self.objectList , tempValue)
end
end
end
function M:ValueMoveDown()
-- 当第二个元素低于警戒值时,便将最后一个元素放到最前面
local temp = self.objectList[2]
if temp:getPositionY() < self.y + self.scrollViewHeight/2 then
if self.par[self.minIndex - 1] then
local minPositionX = self.objectList[1]:getPositionX()
local minPositionY = self.objectList[1]:getPositionY() + self.gapY
local tempValue = table.remove(self.objectList , self.maxShowView)
self.maxIndex = self.maxIndex - 1
self.minIndex = self.minIndex - 1
tempValue:setPosition(minPositionX , minPositionY)
tempValue:Update(self.par[self.minIndex])
table.insert(self.objectList , 1 , tempValue)
else
local maxPositionX = self.objectList[1]:getPositionX()
local maxPositionY = self.objectList[1]:getPositionY() - self.gapY
local tempValue = table.remove(self.objectList , 1)
self.minIndex = #self.par
self.maxIndex = self.maxIndex - 1
tempValue:setPosition(maxPositionX , maxPositionY)
tempValue:Update(self.par[self.minIndex])
table.insert(self.objectList, 1 , tempValue)
end
end
end
function M:TouchEvent()
local x = 0;
local y = 0;
local function onMyTouchBegan(touch,event)
local pos = touch:getLocation()
x = pos.x
y = pos.y
if cc.rectContainsPoint(self.image:getBoundingBox(), self.image:getParent():convertToNodeSpace(cc.p(x, y))) then
return true
end
return false
end
local function onTouchMove(touch,event)
local pos = touch:getLocation()
local rex = pos.x - x
local rey = pos.y - y
x = pos.x
y = pos.y
if rey > 0 then
print("向上移动")
-- 判断向上移动,最下面的元素到没到底点
if self.objectList[#self.objectList] and self.objectList[#self.objectList]:getPositionY() >= (self.y - self.scrollViewHeight/2) and self.maxIndex == #self.par then
return true
end
if self.isQidong then
self:ValueMoveUp()
else
end
elseif rey < 0 then
print("向下移动")
-- 判断向下移动,最上面的元素到没到顶点
if self.objectList[1]:getPositionY() <= (self.y + self.scrollViewHeight/2 - self.gapY) and self.minIndex == 1 then
return true
end
if self.isQidong then
self:ValueMoveDown()
else
end
end
for index,value in pairs(self.objectList) do
value:setPosition(value:getPositionX() , value:getPositionY() + rey)
end
return true
end
local function onMyTouchEnded(touch,event)
end
local touchListen = cc.EventListenerTouchOneByOne:create()
touchListen:setSwallowTouches(false)
touchListen:registerScriptHandler(onMyTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN)
touchListen:registerScriptHandler(onMyTouchEnded,cc.Handler.EVENT_TOUCH_ENDED)
touchListen:registerScriptHandler(onTouchMove,cc.Handler.EVENT_TOUCH_MOVED)
local eventDispatcher = cc.Director:getInstance():getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(touchListen , self.image)
end
-- 获取一个对象
function M:ObtinObject(type)
-- 遍历找下是否有空闲的对象
for index,value in ipairs(self.objectViewList) do
if value:getTag() == 0 then
value:setTag(1)
return value
end
end
-- 没有空闲的对象,则生成一个空闲的对象
local object
if type then
object = self.object:create(type)
else
object = self.object:create()
end
object:setTag(1)
table.insert(self.objectViewList , object)
return object
end
-- 删除一个对象
function M:RemoveObject(value)
if type(value) == "number" then
self.objectViewList[value]:setTag(0)
self.objectViewList[value]:setPosition(-display.width , -display.height)
elseif type(value) == "userData" then
value:setTag(0)
value:setPosition(-display.width , -display.height)
end
end
function M:Update(par,type)
self.par = par
local parLength = Utils.GetTableLength(par)
self.startY = self.scrollViewHeight - self.gapY/2
if parLength > self.maxShowView and self.maxShowView > #self.objectList then
local objectListLength = #self.objectList
self.isQidong = true
self.minIndex = 1
self.maxIndex = self.maxShowView
for index = objectListLength + 1, self.maxShowView do
local value = self:ObtinObject(type)
value:Update(self.par[index])
value:setPosition(self.startX , self.startY - self.gapY * (index - 1))
if value.OnOpen then
value:OnOpen()
end
if type then
value:SwitchState(type)
end
table.insert(self.objectList, value)
self.image:addChild(value)
end
elseif parLength <= self.maxShowView then
self.isQidong = false
self.minIndex = 1
self.maxIndex = parLength
-- 如果需要显示的个数大于当前的元素个数,则生成几个元素个数
local objectListLength = #self.objectList
if parLength > objectListLength then
for index = objectListLength + 1 ,parLength do
local value = self:ObtinObject(type)
if value.OnOpen then
value:OnOpen()
end
self.image:addChild(value)
table.insert(self.objectList, value)
end
-- 如果需要显示的个数小于当前的元素个数,则删掉几个元素个数,但是保留缓存
elseif parLength < objectListLength then
for index = parLength , objectListLength + 1 , -1 do
self.image:removeChild(self.objectList[index] , false)
self:RemoveObject(self.objectList[index])
table.remove(self.objectList , index)
end
end
for i in ipairs(self.par) do
self.objectList[i]:Update(self.par[i])
self.objectList[i]:setPosition(self.startX , self.startY - self.gapY * (i - 1))
if type then
self.objectList[i]:SwitchState(type)
end
end
end
end
function M:OnOpen()
for index , value in ipairs(self.objectList) do
value:OnOpen()
end
end
function M:OnClose()
for index , value in ipairs(self.objectList) do
value:OnClose()
end
end
return M