一.概述
本文缩写说明:sv = ScrollView, cell代表ScrollView的一个子节点
本文介绍sv的一种封装类库,来实现快速创建sv,有如下几个优点:
1.item的位置通过参数控制,提高开发效率
2.免去了调用sv的API,提高开发效率
3.分帧创建,提高性能
4.可通过参数控制,复用item类似tableview,提高性能
本文和上一篇Cocos2dx-lua ScrollView[二]进阶篇-CSDN博客
对比有一定相似之处,但也有较多不同,读者可仔细对比代码实现,详细品读,有所取舍和偏爱
二.效果演示
三.代码实现
3.1 说明
a.下面2个模块需要require
b.svCmn是比较复杂的,有必要阅读代码掌握运行原理
c.代码原封不动搬到工程里基本可以正常运行(当然哪里出了问题读者得会排查,本文基本喂饭喂到嘴里了)
d.svCmn经过上线项目验证,可放心使用,在项目中大量推广
3.2 辅助定时器模块:GlobalTimeTicket
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
3.3 sv封装模块:svCmn
--[[使用例子
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