赞
踩
本文缩写说明:sv = ScrollView, cell代表ScrollView的一个子节点
本文介绍sv的一种封装类库,来实现快速创建sv,有如下几个优点:
1.item的位置通过参数控制,提高开发效率
2.免去了调用sv的API,提高开发效率
3.分帧创建,提高性能
4.可通过参数控制,复用item类似tableview,提高性能
本文和上一篇Cocos2dx-lua ScrollView[二]进阶篇-CSDN博客
对比有一定相似之处,但也有较多不同,读者可仔细对比代码实现,详细品读,有所取舍和偏爱
a.下面2个模块需要require
b.svCmn是比较复杂的,有必要阅读代码掌握运行原理
c.代码原封不动搬到工程里基本可以正常运行(当然哪里出了问题读者得会排查,本文基本喂饭喂到嘴里了)
d.svCmn经过上线项目验证,可放心使用,在项目中大量推广
- GlobalTimeTicket = GlobalTimeTicket or {}
-
- auto_id = auto_id or 0
- function autoId()
- auto_id = auto_id + 1
- return auto_id
- end
- -- 获取单例
- -- New和不New只是一层一层调用__init和__delete,对于单例没有影响
- function GlobalTimeTicket:getInstance()
- if not self.is_init then
- self.scheduler = cc.Director:getInstance():getScheduler()
- self.schedulers = {}
- self.is_init = true
- self.is_stop = nil
- end
- return self
- end
-
- -- 定时回调 通用版
- -- call_back : function 回调函数 必填
- -- interval : int 时间间隔 默认1 秒
- -- limit_time: int 限制次数 默认0 无限
- -- with_name : any 定时器标识 默认自增id
- -- 返回用于删除的标识
- -- simple : local id = GlobalTimeTicket:getInstance():add(fun) ; GlobalTimeTicket:getInstance():remove(id)
- -- : GlobalTimeTicket:getInstance():add(fun, 0.1, 1) -- 次数达到自动删除
- -- : GlobalTimeTicket:getInstance():add(fun, 0.1, 3, "name")
- function GlobalTimeTicket:add(call_back, interval, limit_time, with_name)
- if self.is_stop then return end
- with_name = with_name or autoId()
- if nil == call_back or self.schedulers == nil or nil ~= self.schedulers[with_name] then return end -- 已经有定义了,不能重复
-
- limit_time = limit_time or 0
- interval = interval or 1
- local schedul_hander = self.scheduler:scheduleScriptFunc(function(dt)
- if self.is_stop then return end
- if call_back ~= nil then
- if limit_time == 1 then
- self:remove(with_name)
- elseif limit_time > 1 then
- limit_time = limit_time - 1
- end
- call_back(dt)
- end
- end, interval, false)
- self.schedulers[with_name] = schedul_hander
- return with_name
- end
-
- -- 删除一个定时器
- function GlobalTimeTicket:remove(with_name)
- if with_name == nil then return end
- local schedul_hander = self.schedulers[with_name]
- if schedul_hander ~= nil then
- self.scheduler:unscheduleScriptEntry(schedul_hander)
- self.schedulers[with_name] = nil
- end
- end
-
- -- 清除所有定时器
- function GlobalTimeTicket:removeAll()
- for _, v in pairs(self.schedulers) do
- self.scheduler:unscheduleScriptEntry(v)
- end
- self.schedulers = {}
- end
-
- function GlobalTimeTicket:hasTicket(with_name)
- local schedul_hander = self.schedulers[with_name]
- if schedul_hander ~= nil then
- return true
- end
- return false
- end
-
- function GlobalTimeTicket:getSchedulers()
- return self.schedulers
- end
-
- -- 停止定时器
- function GlobalTimeTicket:stop()
- self.is_stop = true
- self:removeAll()
- end
- --[[使用例子
- if not self.svCmn then
- local setting = {
- start_x = 18, space_x = 0,
- start_y = 26, space_y = 6,
- item_width = 686, item_height = 172,
- row = 1, col = 1,
- delay = 4, once_num = 1,
- }
- self.svCmn = svCmn.new(self.scr_con, cc.p(0,0) , ScrollViewDir.vertical, ScrollViewStartPos.top, self.scr_con:getContentSize(), setting, cc.p(0, 0))
- self.svCmn:registerScriptHandlerSingle(handler(self,self.createNewCell), ScrollViewFuncType.CreateNewCell)
- self.svCmn:registerScriptHandlerSingle(handler(self,self.numberOfCells), ScrollViewFuncType.NumberOfCells)
- self.svCmn:registerScriptHandlerSingle(handler(self,self.updateCellByIndex), ScrollViewFuncType.UpdateCellByIndex)
- end
- self.svCmn:reloadData()
- ]]--
-
- --ScrollView的方法类型
- ScrollViewFuncType = {
- UpdateCellByIndex = 1, -- 更新cell体
- CreateNewCell = 2, -- 创建 新的cell
- NumberOfCells = 3, -- 返回 数据的数量
- OnCellTouched = 4, -- 点击cell回调方法
- }
-
- svCmn = class("svCmn", function()
- return ccui.Layout:create()
- end)
-
- function svCmn:ctor(parent, pos, dir, start_pos, size, setting, ap)
- self.parent = parent
- self.pos = pos or cc.p(0, 0)
- self.dir = dir or ScrollViewDir.vertical
- self.start_pos = start_pos or ScrollViewStartPos.top
- self.size = size or cc.size(100, 100)
- self.ap = ap or cc.p(0, 0)
-
- self.allCellList = {} --存放cell对象和其坐标,结构:{x, y, cell}, cell存在重复对象, 长度=cell总数量
- self.cacheList = {} --保存所有实际创建的cell, 长度=cell最大显示数量
- self.activeCellIdx = {} --保存每个位置的cell当前是否处于显示状态, 长度=cell总数量
- self.handler = {} --回调方法
- self.time_show_index = 0 --到时间显示的索引
- self.is_first_init = true --是否初始化
-
- self:analysisSetting(setting)
- self:createRootWnd()
- end
-
- --要求规定setting的所有变量 都应该在这里定义出来
- function svCmn:analysisSetting(setting)
- self.setting = setting or {}
- self.start_x = self.setting.start_x or 0 -- 第一个单元的起点X
- self.end_x = self.setting.end_x or self.start_x -- 最后一个单元结束X间隔 如果是nil 默认 和 start_x一致
- self.start_y = self.setting.start_y or 0 -- 第一个单元的起点Y
- self.end_y = self.setting.end_y or self.start_y -- 最后一个单元结束Y间隔 如果是nil 默认 和 start_y一致
- self.space_x = self.setting.space_x or 3 -- 横向间隔空间
- self.space_y = self.setting.space_y or 3 -- 竖向间隔空间
- self.item_width = self.setting.item_width or 115 -- 单元的宽度
- self.item_height = self.setting.item_height or 115 -- 单元的高度
-
- self.row = self.setting.row or 5 -- 行数,作用于水平方向的滚动
- self.col = self.setting.col or 5 -- 列数,作用于垂直方向的滚动
- self.delay = 1 --self.setting.delay or 4 -- 创建延迟时间 强制改为1
- self.once_num = self.setting.once_num or 1 -- 每次创建的数量
- self.need_dynamic = true -- 默认是无限的
- self.checkovercallback = self.setting.checkovercallback --滑动回调函数
- self.is_auto_scroll = setting.is_auto_scroll or false --是否自动判断是否能滚动..个数小于一屏大小时候scroll 不能滚动
-
- --位置列表
- self.position_data_list = self.setting.position_data_list
-
- --固定容器大小 如果有值.将不运算容器大小
- self.container_width = setting.container_width
- self.container_height = setting.container_height
-
- self.inner_hight_offset = setting.inner_hight_offset or 0 -- 内容高度偏移值(仅对纵向有效)
-
- --横向的只支持一行的..
- if self.dir == ScrollViewDir.horizontal then
- self.row = 1
- end
- self:calculationMaxSum()
- end
-
- function svCmn:updateSetting(setting)
- if not setting then return end
- for k,v in pairs(setting) do
- self[k] = v
- end
- end
-
- --desc:计算一下一屏最多创建的个数
- function svCmn:calculationMaxSum()
- local max_sum
- if self.dir == ScrollViewDir.horizontal then
- max_sum = (math.ceil(self.size.width / (self.item_width + self.space_x)) + 1) * self.row
- else
- max_sum = (math.ceil(self.size.height / (self.item_height + self.space_y)) + 1) * self.col
- end
- self.cacheMaxSize = max_sum
- end
-
- function svCmn:createRootWnd()
- self:setContentSize(self.size)
- if not tolua.isnull(self.parent) then
- self.parent:addChild(self)
- end
- self:setPosition(self.pos)
- self:setAnchorPoint(self.ap)
-
- self.scroll_view = createScrollView(self.size.width, self.size.height, 0, 0, self, self.dir)
- self.container = self.scroll_view:getInnerContainer()
- self:registerEvent()
- end
-
- function svCmn:registerEvent()
- if self.need_dynamic == true then
- self.scroll_view:addEventListener(function(sender, eventType)
- if eventType == ccui.ScrollviewEventType.containerMoved then
- self:checkRectIntersectsRect()
- if self.checkovercallback then
- self.checkovercallback()
- end
- end
- end)
- end
- end
-
- function svCmn:registerScriptHandlerSingle(func, handlerId)
- self.handler[handlerId] = func
- end
-
- function svCmn:numberOfCells()
- local cells = ScrollViewFuncType.NumberOfCells
- if not self.handler or not self.handler[cells] then return end
- return self.handler[cells]()
- end
-
- --刷新每一个cell
- function svCmn:updateCellByIndex(cell, index)
- if not self.handler[ScrollViewFuncType.UpdateCellByIndex] then return end
- if not cell.index then
- cell.create_index = index
- end
- print("item刷新ing", "item创建时的索引:"..cell.create_index, "item数据索引变化:" .. (cell.index or "无") .. " -> " .. index)
- self.handler[ScrollViewFuncType.UpdateCellByIndex](cell, index)
- end
-
- --创建一个新cell
- function svCmn:createNewCell(idx)
- if not self.handler[ScrollViewFuncType.CreateNewCell] then return end
- print("createNewCell", idx)
- return self.handler[ScrollViewFuncType.CreateNewCell](self.item_width, self.item_height, idx)
- end
-
- -- --点击cell --在createNewCell 自行实现
- function svCmn:onCellTouched(cell, index)
- if not self.handler[ScrollViewFuncType.OnCellTouched] then return end
- self.handler[ScrollViewFuncType.OnCellTouched](cell, index)
- end
-
-
- --设置 scrollview 是否可点
- function svCmn:setClickEnabled(status)
- self.scroll_view:setTouchEnabled(status)
- end
- --设置 是否吞噬点击
- function svCmn:setSwallowTouches(status)
- self.scroll_view:setSwallowTouches(status)
- end
-
- function svCmn:setBounceEnabled( status )
- self.scroll_view:setBounceEnabled(status)
- end
-
- --desc:移动的过程中盘点是否不再可视范围,不再的时候移除掉,放到对象池,并且准备下一次创建
- function svCmn:checkRectIntersectsRect()
- if self.dir == ScrollViewDir.vertical then
- if self.start_pos == ScrollViewStartPos.top then
- self:checkOverShowByVertical()
- else
- -- 支持ScrollViewStartPos.bottom的了 --by lwc
- self:checkOverShowByVerticalBottom()
- end
- elseif self.dir == ScrollViewDir.horizontal then
- self:checkOverShowByHorizontal()
- end
- end
-
- function svCmn:checkOverShowByVertical()
- if not self.allCellList then return end
- local container_y = self.container:getPositionY()
- --计算 视图的上部分和下部分在self.container 的位置
- local bot = -container_y
- local top = self.size.height + bot
- local col_count = math.ceil(#self.allCellList/self.col)
- --下面因为 self.allCellList 是一维数组 所以要换成二维来算
- --活跃cell开始行数
- local activeCellStartRow = 1
- for i=1, col_count do
- local index = 1 + (i-1)* self.col
- local cell = self.allCellList[index]
- activeCellStartRow = i
- if cell and cell.y - self.item_height * 0.5 <= top then
- break
- end
- end
- --活跃cell结束行数
- local activeCellEndRow = col_count
- if bot > 0 then
- for i = activeCellStartRow, col_count do
- local index = 1 + (i-1)* self.col
- local cell = self.allCellList[index]
- if cell and cell.y + self.item_height * 0.5 < bot then
- activeCellEndRow = i - 1
- break
- end
- end
- end
- -- print("@保留--> top --> :"..top .." self.col:"..self.col)
- -- print("@保留--> bot --> :"..bot )
- -- print("@保留--> 开始行: "..activeCellStartRow.."@结束行: "..activeCellEndRow)
- local max_count = self:numberOfCells()
- if max_count then
- for i=1, col_count do
- if i >= activeCellStartRow and i <= activeCellEndRow then
- for k=1, self.col do
- local index = (i-1) * self.col + k
- if not self.activeCellIdx[index] then
- if index <= max_count then
- self:updateCellAtIndex(index)
- self.activeCellIdx[index] = true
- end
- end
- end
- else
- for k=1, self.col do
- local index = (i-1) * self.col + k
- if index <= max_count then
- self.activeCellIdx[index] = false
- end
- end
- end
- end
- end
- end
-
- function svCmn:checkOverShowByVerticalBottom()
- if not self.allCellList then return end
- local container_y = self.container:getPositionY()
- --计算 视图的上部分和下部分在self.container 的位置
- local bot = -container_y
- local top = self.size.height + bot
- local col_count = math.ceil(#self.allCellList/self.col)
- --下面因为 self.allCellList 是一维数组 所以要换成二维来算
- --活跃cell开始行数
- local activeCellStartRow = col_count
- for i=col_count, 1,-1 do
- local index = 1 + (i-1)* self.col
- local cell = self.allCellList[index]
- activeCellStartRow = i
- if cell and cell.y - self.item_height * 0.5 <= top then
- break
- end
- end
- --活跃cell结束行数
- local activeCellEndRow = 1
- if bot > 0 then
- for i = activeCellStartRow, 1, -1 do
- local index = 1 + (i-1)* self.col
- local cell = self.allCellList[index]
- if cell and cell.y + self.item_height * 0.5 < bot then
- activeCellEndRow = i + 1
- break
- end
- end
- end
- -- print("@保留--> top --> :"..top .." self.col:"..self.col)
- -- print("@保留--> bot --> :"..bot )
- -- print("@保留--> 开始行: "..activeCellStartRow.."@结束行: "..activeCellEndRow)
- local max_count = self:numberOfCells()
- for i=1, col_count do
- if i <= activeCellStartRow and i >= activeCellEndRow then
- for k=1, self.col do
- local index = (i-1) * self.col + k
- if not self.activeCellIdx[index] then
- if index <= max_count then
- self:updateCellAtIndex(index)
- self.activeCellIdx[index] = true
- end
- end
- end
- else
- for k=1, self.col do
- local index = (i-1) * self.col + k
- if index <= max_count then
- self.activeCellIdx[index] = false
- end
- end
- end
- end
- end
-
- function svCmn:checkOverShowByHorizontal()
- if not self.allCellList then return end
-
- local container_x = self.container:getPositionX()
- --计算 视图的左部分和右部分在self.container 的位置
- local top = -container_x
- local bot = top + self.size.width
-
- local row_count = #self.allCellList
- --横向的只支持一行
- --活跃cell开始行数
- local activeCellStartRow = 1
- if top > 0 then
- for index=1, row_count do
- local cell = self.allCellList[index]
- activeCellStartRow = index
- if cell and cell.x + self.item_width * 0.5 >= top then
- break
- end
- end
- end
- --活跃cell结束行数
- local activeCellEndRow = row_count
- for index = activeCellStartRow, row_count do
- local cell = self.allCellList[index]
- if cell and cell.x - self.item_width * 0.5 > bot then
- activeCellEndRow = index - 1
- break
- end
- end
- -- print("@保留--> top --> :"..top .." self.row:"..self.row)
- -- print("@保留--> bot --> :"..bot )
- -- print("@保留--> 开始行: "..activeCellStartRow.."@结束行: "..activeCellEndRow)
- local max_count = self:numberOfCells()
- if max_count then
- for index=1, row_count do
- if index >= activeCellStartRow and index <= activeCellEndRow then
- if not self.activeCellIdx[index] then
- if index <= max_count then
- self:updateCellAtIndex(index)
- self.activeCellIdx[index] = true
- end
- end
- else
- if index <= max_count then
- self.activeCellIdx[index] = false
- end
- end
- end
- end
- end
-
- --desc:滚动容器移动到指定位置
- function svCmn:updateMove(pos)
- local target_pos = self:checkPosition(pos.x, pos.y)
- local move_to = cc.MoveTo:create(0.1, cc.p(target_pos.x, target_pos.y))
- local ease_out = cc.EaseSineOut:create(move_to)
- self.container:runAction(cc.Sequence:create(ease_out))
- end
-
- function svCmn:jumpToMove(pos, time, callback)
- local target_pos = self:checkPosition(pos.x, pos.y)
- time = time or 1
- local move_to = cc.MoveTo:create(time, cc.p(target_pos.x, target_pos.y))
- self.container:runAction(cc.Sequence:create(move_to, cc.CallFunc:create(function()
- if callback then
- callback()
- end
- end)))
- end
-
- function svCmn:checkPosition(x, y)
- local _x, _y = self.container:getPositionX(), self.container:getPositionY()
- if self.dir == ScrollViewDir.horizontal then
- _x = _x + x
- elseif self.dir == ScrollViewDir.vertical then
- _y = _y + y
- end
- if _x > 0 then
- _x = 0
- elseif _x < (self.size.width - self.container_size.width) then
- _x = self.size.width - self.container_size.width
- end
-
- if _y > 0 then
- _y = 0
- elseif _y < (self.size.height - self.container_size.height) then
- _y = self.size.height - self.container_size.height
- end
- return cc.p(_x, _y)
- end
-
- --获取当前容器的y位置
- function svCmn:getCurContainerPosY()
- if self.container and not tolua.isnull(self.container) then
- return self.container:getPositionY()
- end
- end
- --获取当前容器的x位置
- function svCmn:getCurContainerPosX()
- if self.container and not tolua.isnull(self.container) then
- return self.container:getPositionX()
- end
- end
-
- function svCmn:setInnerContainer()
- local number = self:numberOfCells()
- local container_width = self.container_width or self.size.width
- local container_height = self.container_height or self.size.height
- if self.dir == ScrollViewDir.horizontal then -- 水平
- if self.container_width == nil then
- local num = math.ceil(number / self.row)
- container_width = num * self.item_width + self.end_x + self.start_x + (num - 1) * self.space_x
- end
- else
- if self.container_height == nil then
- local num = math.ceil(number / self.col)
- container_height = num * self.item_height + self.end_y + self.start_y + (num - 1) * self.space_y + self.inner_hight_offset
- end
- end
- container_width = math.max(container_width, self.size.width)
- container_height = math.max(container_height, self.size.height)
- self.container_size = cc.size(container_width, container_height)
- --记录在当前的contariner位置..因为在 setInnerContainerSize 方法会被重置
- self.cur_container_x, self.cur_container_y = self.container:getPosition()
-
- self.scroll_view:setInnerContainerSize(self.container_size)
- if self.start_pos == ScrollViewStartPos.top then
- self.scroll_view:jumpToTop()
- elseif self.start_pos == ScrollViewStartPos.bottom then
- self.scroll_view:jumpToBottom()
- end
- end
-
- --刷新当前显示的item数据 (不改变任何位置的,前提数据数量没有改变如果有改变用 reload)
- function svCmn:resetCurrentItems()
- for i,v in pairs(self.activeCellIdx) do
- if v then
- self:updateCellAtIndex(i)
- end
- end
- end
-
- --根据index 刷新对应索引..如果在显示视图内
- function svCmn:resetItemByIndex(index)
- -- body
- if self.activeCellIdx[index] then
- self:updateCellAtIndex(index)
- end
- end
-
- --获取活跃中的cell对象
- function svCmn:getActiveCellList()
- local list = {}
- for i,v in pairs(self.activeCellIdx) do
- if v and self.allCellList[i] and self.allCellList[i].cell then
- table.insert(list, self.allCellList[i].cell)
- end
- end
- return list
- end
-
- --获取index索引对应cell(不管是否活跃)
- function svCmn:getCellByIndex(index)
- if self.allCellList[index] and self.allCellList[index].cell then
- return self.allCellList[index].cell
- end
- end
-
- --获取index索引对应cellXY位置(不管是否活跃)
- function svCmn:getCellXYByIndex(index)
- if self.allCellList[index] then
- return self.allCellList[index].x, self.allCellList[index].y
- end
- end
-
- --获取index索引对应cellXY位置(不活跃会返回空)
- function svCmn:getActiveCellByIndex(index)
- if self.activeCellIdx[index] and self.allCellList[index] then
- return self.allCellList[index].cell
- end
- end
- --获取当前容器所在显示窗口的x y位置
- function svCmn:getContainerXY()
- if self.container then
- local x, y = self.container:getPosition()
- return x, y
- end
- end
-
- --获取当前容器所在显示窗口的x y位置
- function svCmn:setContainerXY(x, y)
- if self.container then
- if x and y then
- self.container:setPosition(x,y)
- else
- if x then
- self.container:setPositionX(x)
- end
- if y then
- self.container:setPositionY(y)
- end
- end
- end
- end
-
- --根据索引判断是否活跃中
- function svCmn:isActiveByIndex(index)
- if self.activeCellIdx[index] then
- return true
- end
- return false
- end
- --移动到以选中idenx的位置作为在中间 显示 目前只支持y 方向的
- function svCmn:jumpToMoveByIndex(index)
-
- if not self.allCellList[index] then return end
- local y = self.allCellList[index].y or 0
- local pos = self.container_size.height - (y + self.size.height * 0.5 )
- if pos < 0 then
- pos = 0
- end
- local pos_per = pos * 100 / (self.container_size.height - self.size.height)
- if pos_per ~= pos_per then
- pos_per = 0;
- end
- if pos_per > 100 then
- pos_per = 100
- end
- if pos_per == 100 then
- if self.start_pos == ScrollViewStartPos.top then
- self:checkOverShowByVertical()
- else
- self:checkOverShowByVerticalBottom()
- end
- end
- self.scroll_view:scrollToPercentVertical(pos_per, 0.8, true)
- end
-
- --desc:设置数据
- --select_idnex 从第几个开始
- --@setting: 如果有改变的话
- --@is_keep_position 是否保持原来位置 --item数量有变化情况. 无变化请用resetCurrentItems
- function svCmn:reloadData(select_index, setting, is_keep_position)
- if setting then
- self:updateSetting(setting)
- end
- local old_width , old_height = 0, 0
- if self.container_size then
- old_width = self.container_size.width
- old_height = self.container_size.height
- end
- self.allCellList = {}
- self.activeCellIdx = {}
-
- for k, v in ipairs(self.cacheList) do
- --相当于隐藏
- v:setPositionX(-10000)
- end
- --设置容器大小
- self:setInnerContainer()
-
- local number = self:numberOfCells()
- if number == 0 then
- return
- end
-
- for i = 1, number do
- local cell = nil
- if i <= self.time_show_index then
- cell = self:getCacheCellByIndex(i)
- end
- local count = #self.allCellList
- local x, y
- if self.position_data_list then
- local pos = self.position_data_list[count + 1]
- if pos then
- x, y = pos.x, pos.y
- else
- x, y = self:getCellPosition(count + 1)
- end
- else
- x, y = self:getCellPosition(count + 1)
- end
- local cellData = {cell = cell, x = x, y = y}
- table.insert(self.allCellList, cellData)
- end
-
- if self.is_first_init then
- self:startTimeTicket()
- else
- --如果时间显示索引小于总数 应该显示继续当前定时器 让下面的能显示出来
- if self.time_show_index <= number then
- self:startTimeTicket()
- end
- end
-
- if is_keep_position then
- --是否保持当前显示位置
- local cur_container_x = self.cur_container_x or 0
- local cur_container_y = self.cur_container_y or 0
- if self.dir == ScrollViewDir.vertical then --竖方向
- if self.start_pos == ScrollViewStartPos.top then
- local temp_height = self.container_size.height - old_height
- cur_container_y = cur_container_y - temp_height
- end
- if cur_container_y > 0 then
- cur_container_y = 0
- elseif cur_container_y < (self.size.height - self.container_size.height) then
- cur_container_y = self.size.height - self.container_size.height
- end
- elseif self.dir == ScrollViewDir.horizontal then --横方向
- if cur_container_x > 0 then
- cur_container_x = 0
- elseif cur_container_x < (self.size.width - self.container_size.width) then
- cur_container_x = self.size.width - self.container_size.width
- end
- end
- self.container:setPosition(cur_container_x, cur_container_y)
- self:checkRectIntersectsRect()
- else
- if select_index == nil then
- local maxRefreshNum
- if self.dir == ScrollViewDir.horizontal then -- 水平
- maxRefreshNum = self.cacheMaxSize - self.row
- else
- maxRefreshNum = self.cacheMaxSize - self.col
- end
- local refreshNum = number < maxRefreshNum and number or maxRefreshNum
-
- for i = 1, refreshNum do
- if i <= self.time_show_index then
- self:updateCellAtIndex(i)
- end
- self.activeCellIdx[i] = true
- end
- else
- self:selectCellByIndex(select_index)
- end
- end
- if self.is_auto_scroll then
- local cur_max_count = self.cacheMaxSize
-
- if self.dir == ScrollViewDir.horizontal then
- cur_max_count = cur_max_count - 2 * self.row
- else
- cur_max_count = cur_max_count - 2 * self.col
- end
- if number <= cur_max_count then
- self:setClickEnabled(false)
- else
- self:setClickEnabled(true)
- end
- end
- end
-
- --选中index索引对象(如果列表允许 会排序在开始第一位)
- function svCmn:selectCellByIndex(index)
- local index = index or 1
- if self.allCellList[index] == nil then
- index = 1
- end
- if self.allCellList[index] == nil then return end
- --一屏幕显示的最大数量
- local maxRefreshNum
- if self.dir == ScrollViewDir.horizontal then -- 水平
- maxRefreshNum = self.cacheMaxSize - self.row
- else
- maxRefreshNum = self.cacheMaxSize - self.col
- end
- local number = self:numberOfCells()
- if number < maxRefreshNum then
- --不够显示一屏幕
- if self.time_show_index == 0 then
- self.time_show_index = index
- end
- for i = 1, number do
- if i <= self.time_show_index then
- self:updateCellAtIndex(i)
- end
- self.activeCellIdx[i] = true
- end
- else
- --列表允许 情况
- if self.dir == ScrollViewDir.horizontal then -- 水平
- --容器x方向位置
- local container_x
- if index == 1 then
- container_x = 0
- else
- container_x = -(self.allCellList[index].x - (self.item_width + self.space_x) * 0.5 )
- end
- --容器x方向最大位置
- local max_contariner_x = -(self.container_size.width - self.size.width)
-
- --这两个值都是负数
- if container_x < max_contariner_x then
- container_x = max_contariner_x
- end
- local show_index = math.floor(math.abs(container_x) / self.item_width) + 1
- if self.time_show_index < show_index then
- self.time_show_index = show_index
- end
- self.container:setPositionX(container_x)
- self:checkRectIntersectsRect()
- else -- 垂直
- local container_y
- if index == 1 then
- container_y = (self.start_y + self.allCellList[index].y + self.item_height * 0.5) - self.size.height
- else
- container_y = (self.allCellList[index].y + (self.item_height + self.space_y) * 0.5) - self.size.height
- end
- if container_y < 0 then
- container_y = 0
- end
- local index_1 = math.floor( (self.container_size.height - (container_y + self.size.height)) / self.item_height) + 1
- local show_index = (index_1 - 1) * self.col + 1
- if self.time_show_index < show_index then
- self.time_show_index = show_index
- end
- self.container:setPositionY(- container_y)
- self:checkRectIntersectsRect()
- end
- end
-
- if index > 0 and index <= self:numberOfCells() then
- local cell = self:getCacheCellByIndex(index)
- cell.index = index
- self.allCellList[index].cell = cell
- self:onCellTouched(cell, index)
- end
- end
-
- function svCmn:setOnCellTouched(index)
- local cell = self:getCacheCellByIndex(index)
- cell.index = index
- self.allCellList[index].cell = cell
- self:onCellTouched(cell, index)
- end
-
- function svCmn:startTimeTicket()
- if self.time_ticket == nil then
- if #self.allCellList == 0 then
- return
- end
- --到时间显示的索引
- local once_num = self.once_num or 1
- local _callback = function()
- if tolua.isnull(self.container) then return end
- local count = self.time_show_index + once_num
- local index = self.time_show_index + 1
- if index == 0 then
- index = 1
- end
- local size = #self.allCellList
-
- self.time_show_index = self.time_show_index + once_num
- for i = index, count do
- if i > size then
- --超过总数了
- break
- end
- local cellData = self.allCellList[i]
- if cellData and cellData.cell == nil then
- cellData.cell = self:getCacheCellByIndex(i)
- end
- if self.activeCellIdx[i] then
- self:updateCellAtIndex(i)
- end
- end
-
- if self.time_show_index >= size then
- self:clearTimeTicket()
- self.is_first_init = false
- end
- end
-
- self.time_ticket = GlobalTimeTicket:getInstance():add(_callback, self.delay / display.DEFAULT_FPS)
- end
- end
-
- function svCmn:clearTimeTicket()
- if self.time_ticket ~= nil then
- GlobalTimeTicket:getInstance():remove(self.time_ticket)
- self.time_ticket = nil
- end
- end
-
- function svCmn:getCellPosition(index)
- local cur_item_index = index
- local anchor_point = cc.p(0.5,0.5)
- local _x, _y = 0, 0
- if self.dir == ScrollViewDir.horizontal then
- _x = self.start_x + self.item_width * anchor_point.x +(self.item_width + self.space_x) *(math.floor((index - 1) / self.row))
- _y = self.container_size.height -(self.start_y + self.item_height *(1 - anchor_point.y) +((index - 1) % self.row) *(self.item_height + self.space_y))
- else
- if self.start_pos == ScrollViewStartPos.top then
- _x = self.start_x + self.item_width * anchor_point.x + (self.item_width + self.space_x) *((index - 1) % self.col)
- _y = self.container_size.height -(self.start_y + self.item_height *(1 - anchor_point.y) +(math.floor((index - 1) / self.col)) *(self.item_height + self.space_y))
- else
- _x = self.start_x + self.item_width * anchor_point.x +(self.item_width + self.space_x) *((index - 1) % self.col)
- _y = self.start_y + self.item_height * anchor_point.y +(math.floor((index - 1) / self.col)) *(self.item_height + self.space_y)
- end
- end
- return _x, _y
- end
-
- --通过创建或复用的方式,获取index对应的cell对象
- function svCmn:getCacheCellByIndex(index)
- local cacheIndex = (index - 1) % self.cacheMaxSize + 1
- if not self.cacheList[cacheIndex] then
- local newCell = self:createNewCell(index)
- if newCell then
- newCell:setAnchorPoint(cc.p(0.5, 0.5))
- newCell:setPositionX(-10000)--隐藏
- self.cacheList[cacheIndex] = newCell
- self.scroll_view:addChild(newCell)
- end
- return newCell
- else
- return self.cacheList[cacheIndex]
- end
- end
-
- --cell设置位置,并刷新cell的UI
- function svCmn:updateCellAtIndex(index)
- if index > self.time_show_index then
- return
- end
- if not self.allCellList[index] then return end
- local cellData = self.allCellList[index]
- if cellData.cell == nil then
- cellData.cell = self:getCacheCellByIndex(index) --self.allCellList的cell赋值在这里
- end
- cellData.cell:setPosition(cellData.x, cellData.y)
- self:updateCellByIndex(cellData.cell, index)
- end
-
- function svCmn:clearTimeTicket()
- if self.time_ticket ~= nil then
- GlobalTimeTicket:getInstance():remove(self.time_ticket)
- self.time_ticket = nil
- end
- end
-
- function svCmn:getMaxSize()
- return self.container_size
- end
-
- function svCmn:getContainer()
- return self.container
- end
-
- function svCmn:scrollToPercentVertical( percent, time )
- if percent ~= percent then percent = 0 end
- self.scroll_view:scrollToPercentVertical(percent, time, true)
- end
-
- function svCmn:DeleteMe()
- doStopAllActions(self.container)
- self:clearTimeTicket()
- for k, item in ipairs(self.cacheList) do
- if item.DeleteMe then
- item:DeleteMe()
- end
- end
- self.allCellList = nil
- self.activeCellIdx = nil
- self.cacheList = nil
- self:removeAllChildren()
- self:removeFromParent()
- end
- function ModuleTest:updateSVCmn()
- self.cellData = {
- [1] = {index = 1},
- [2] = {index = 2},
- [3] = {index = 3},
- [4] = {index = 4},
- [5] = {index = 5},
- [6] = {index = 6},
- [7] = {index = 7},
- [8] = {index = 8},
- [9] = {index = 9},
- [10] = {index = 10},
- [11] = {index = 11},
- [12] = {index = 12},
- }
- if not self.svCmn then
- local setting = {
- start_x = 18, space_x = 0,
- start_y = 26, space_y = 6,
- item_width = 686, item_height = 172,
- row = 1, col = 1,
- delay = 4, once_num = 1,
- }
- self.svCmn = svCmn.new(self.scr_con, cc.p(0,0) , ScrollViewDir.vertical, ScrollViewStartPos.top, self.scr_con:getContentSize(), setting, cc.p(0, 0))
- self.svCmn:registerScriptHandlerSingle(handler(self,self.createNewCell), ScrollViewFuncType.CreateNewCell)
- self.svCmn:registerScriptHandlerSingle(handler(self,self.numberOfCells), ScrollViewFuncType.NumberOfCells)
- self.svCmn:registerScriptHandlerSingle(handler(self,self.updateCellByIndex), ScrollViewFuncType.UpdateCellByIndex)
- end
- self.svCmn:reloadData()
- end
-
- function ModuleTest:createNewCell(width, height)
- local cell = ActionCommonItem.new()
- return cell
- end
-
- function ModuleTest:numberOfCells()
- if not self.cellData then return 0 end
- return #self.cellData
- end
-
- function ModuleTest:updateCellByIndex(cell, index)
- local onecellData = self.cellData[index]
- cell.root_wnd:getChildByName("label"):setString(onecellData.index)
- end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。