• unity滑动列表简单优化(资源复用)


    实现功能:基于UGUI自带的ScrollRect,对列表元素进行复用
    基本思路:在原生ScrollRect的基础上,添加onValueChanged监听,通过Content节点的anchoredPosition来判断当前可见的第一个元素的索引值,回收超出视图的部分,加载出视图上的所有元素(对回收的元素进行复用)
    与上一版的区别:删除了网格布局(Grid Layout Group)和内容大小适配器(Content Size Fitter)的使用
    PS:一定要先计算好Content的sizeDelta,这边元素的预制体锚点设置在(0.5, 0.5)。
    核心部分代码:
     function M:initialize()
        --- 当前的index
        self._index         = -1
        --- 可视的item链表
        self._itemList      = {}
        --- 未使用的池子
        self._unUseQueue    = {}    
        --- 存储已经加载过的sprite
        self._picSprites = {}
    end
    
    --- 初始化数值参数
    function M:initParams()
        self._rowNum        = 2
        --- 列表数量
        self._count         = 20
        self._colNum        = Mathf.CeilToInt(self._count/self._rowNum)
        --- item的大小
        self._cellSize      = Vector2(225, 225)--self._gridGroup.cellSize
        --- 间隔
        self._spacing       = Vector2(6.5, 10)--self._gridGroup.spacing
        --- 可视列数量
        self._viewCount     = Mathf.CeilToInt(CAMERA_WIDTH * 200/(self._cellSize.x +  self._spacing.x)) + 2
        --- 设置content的大小
        self._content.sizeDelta = Vector2(self._cellSize.x * self._colNum + (self._spacing.x * self._colNum - 1), self._cellSize.y * self._rowNum + self._spacing.y * (self._rowNum - 1))
    end
    
    --- 值变化
    function M:onValueChanged(pos)
        local index = self:getPosIndex()
        if self._index ~= index and index > -1 then
            self._index = index
            for i = #self._itemList, 1, -1 do
                local item = self._itemList[i]
                if item._col < index or item._col > index + self._viewCount then
                    --- 收入回收池
                    self:addUnUseQueue(item, i)
                end
            end
            for i = self._index, self._index + self._viewCount do
                if i > 0 and i <= self._colNum then
                    local isOk = false
                    for k,v in pairs(self._itemList) do
                        if v._col == i then
                            isOk = true
                            -- break
                        end
                    end
                    if not isOk then
                        self:createItem(1, i)
                        self:createItem(2, i)
                    end
                end
            end
        end
    end
    
    --- 收入回收池
    function M:addUnUseQueue(item, i)
        table.remove(self._itemList, i)
        item:unUse()
        table.insert(self._unUseQueue, item)
    end
    
    --- 创建元素
    function M:createItem(row, col)
        if (col - 1) * 2 + row > self._count then return end
        local item = nil
        if #self._unUseQueue > 0 then
            item = table.remove(self._unUseQueue, 1)
        else
            item = self:createNewItem()
        end
        item:recycle()
        item:updateData(row, col)
        item._rectTF.anchoredPosition = self:getPosition(row, col)
        table.insert(self._itemList, item)
    end
    
    --- 创建一个新的可用的元素
    function M:createNewItem()
        local go = UnityEngine.GameObject.Instantiate(self._iconPre, self._content)
        local item = go.transform:GetLuaTable()
        return item
    end
    
    --- 获取当前位置的index
    function M:getPosIndex()
        -- print(self._content.anchoredPosition.x)
        return Mathf.FloorToInt(self._content.anchoredPosition.x / -(self._cellSize.x + self._spacing.x))
    end
    
    --- 获取当前位置
    function M:getPosition(row, col)
        local y = row == 1 and (self._cellSize.y + self._spacing.y) or -(self._cellSize.y + self._spacing.y)
        return Vector3((col - 0.5) * (self._cellSize.x + self._spacing.x), y/2, 0)
    end
  • 相关阅读:
    任务Task系列之Parallel的静态For,ForEach,Invoke方法
    任务Task系列之使用CancellationToken取消Task
    泛型基础
    串的两种模式匹配算法
    数据结构之串类型
    c#基础知识之设计类型
    挣脱
    数据结构之栈和队列
    数据结构之线性表
    NGUI背包系统
  • 原文地址:https://www.cnblogs.com/XxZzYy/p/16143716.html
Copyright © 2020-2023  润新知