Unity-UGUI无限循环列表

Unity版本:2017.4

简介:
UGUI使用ScrollView、GridLayoutGroup实现无限循环列表,支持数据刷新,支持跳转,支持动态插入/删除

使用说明:
点击UI中的ID进行删除,键盘按下A添加ID。
在Inspector面板中输入MaxItemCount 列表最大数量。TargetID输入要跳转的ID,键盘按下Space跳转到要查找的ID。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CSInfiniteScrolling : MonoBehaviour
{

    public int maxItemCount = 0;
    public int targetID = 0;

    private int rowCount = 0;
    private int columnCount = 0;
    private int curTopIndex = 0;
    private int initializedBottomIndex = 0;
    private int curBottomIndex = 0;
    private int contentCurTopPosY = 0;
    private int oneBlockHeight = 0;
    private int curIndex = 0;

    private List itemIDs;

    private ScrollRect scrollRect;
    private RectTransform content;
    private GridLayoutGroup contentGridLayoutGroup;

    private void Awake()
    {
        scrollRect = GetComponent();

        content = scrollRect.content;
        contentGridLayoutGroup = content.GetComponent();


        columnCount = (int)(content.rect.width - contentGridLayoutGroup.spacing.x) / (int)contentGridLayoutGroup.cellSize.x;
        if (columnCount != 0)
        {
            rowCount = (int)Mathf.Ceil(content.transform.childCount / columnCount);
            curBottomIndex = (rowCount - 1) * columnCount;
            initializedBottomIndex = curBottomIndex;
        }

        oneBlockHeight = (int)(contentGridLayoutGroup.cellSize.y + contentGridLayoutGroup.spacing.y);
        content.sizeDelta = new Vector2(content.sizeDelta.x, (int)Mathf.Ceil((float)maxItemCount / (float)columnCount) * oneBlockHeight);//向上取整

        itemIDs = new List();
        for (int i = 0; i < maxItemCount; i++)
        {
            itemIDs.Add(i);
        }

    }

    // Use this for initialization
    void Start()
    {
        scrollRect = GetComponent();
        scrollRect.onValueChanged.AddListener(ListenerMethod);
        FreshBackpack();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            JumpToTargetID(targetID);
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            AddRandomID();
            FreshBackpack();
        }
    }

    private void AddRandomID()
    {
        if (itemIDs.Count {
                itemIDs.RemoveAt(index);
                FreshBackpack();
            });
            transformChild.GetComponent

物品没有直接挂载Button,通过代码控制Button的挂载

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PressToDelID : MonoBehaviour {
    private Button button;
    private void Awake()
    {
        button = gameObject.GetComponent

用Lua实现

import "UnityEngine"
import "UnityEngine.UI"

local breakSocketHandle,debugXpCall = require("LuaDebugjit")("localhost",7003)
LuaTimer.Add(0,1000,function(id)
    breakSocketHandle()
end)

local scrollRect;
local content;
local contentGridLayoutGroup;
local columnCount;
local rowCount;
local initializedBottomIndex;
local oneBlockHeight;
local maxItemCount = 0;
local itemIDs = {};
local scrollRect;

local contentCurTopPosY = 0;
local curTopIndex = 0;
local curBottomIndex = 0;
local curIndex = 1;

local class = {}

function main()
    maxItemCount = 40;

    scrollRect = GameObject.Find("Canvas/Backpack"):GetComponent(UI.ScrollRect);
    
    content = scrollRect.content;
    contentGridLayoutGroup = content:GetComponent(UI.GridLayoutGroup);

    columnCount = math.floor((content.rect.width - contentGridLayoutGroup.spacing.x)/contentGridLayoutGroup.cellSize.x);
    if columnCount ~= 0 then
        rowCount = math.ceil( content.childCount/columnCount );
        curBottomIndex = (rowCount - 1)*columnCount;
        initializedBottomIndex = curBottomIndex;
    end

    oneBlockHeight = contentGridLayoutGroup.cellSize.y + contentGridLayoutGroup.spacing.y;
    local contentSizeDeltaY = math.floor( oneBlockHeight * (math.ceil(maxItemCount / columnCount))) ;
    content.sizeDelta = UnityEngine.Vector2(content.sizeDelta.x,contentSizeDeltaY);

    for i=1,maxItemCount do
        table.insert(itemIDs,i);
    end

    scrollRect.onValueChanged:AddListener(ListenerMethod);
    FreshBackpack();

    return class;
end

function class : Update()
    if UnityEngine.Input.GetKeyDown(KeyCode.Space) then
        JumpToTargetID(12);
    end
    if UnityEngine.Input.GetKeyDown(KeyCode.A) then
        if #itemIDs < maxItemCount then
            table.insert( itemIDs,math.random(0,100) );
            FreshBackpack();
        else
            print("BP Full!");
        end
    end
end

function ListenerMethod()
    if ((content.localPosition.y - contentCurTopPosY) > oneBlockHeight) then
        while ((content.localPosition.y - contentCurTopPosY) > oneBlockHeight)
            do
                contentCurTopPosY = contentCurTopPosY + oneBlockHeight;
                for i=1,columnCount do
                    local child = content.transform:GetChild(curTopIndex + i - 1);
                    local rectTransform = child:GetComponent(UnityEngine.RectTransform);
                    rectTransform.anchoredPosition = UnityEngine.Vector2(rectTransform.anchoredPosition.x, rectTransform.anchoredPosition.y - oneBlockHeight * rowCount);
                end
                curTopIndex = curTopIndex + columnCount;
                curBottomIndex =    curBottomIndex+ columnCount;
                curTopIndex = curTopIndex % content.childCount;
                curBottomIndex = curBottomIndex % content.childCount;
                curIndex =curIndex+ columnCount;
            end
            FreshBackpack();
    elseif ((content.localPosition.y - contentCurTopPosY) < -contentGridLayoutGroup.spacing.y) then
        while ((content.localPosition.y - contentCurTopPosY) < -contentGridLayoutGroup.spacing.y) do
                contentCurTopPosY = contentCurTopPosY - oneBlockHeight;
                for i=1,columnCount do
                    local rectTransform = content.transform:GetChild(curBottomIndex + i -1):GetComponent(UnityEngine.RectTransform);
                    rectTransform.anchoredPosition = UnityEngine.Vector2(rectTransform.anchoredPosition.x, rectTransform.anchoredPosition.y + oneBlockHeight * rowCount);
                end
                curTopIndex = (curTopIndex + content.childCount) - columnCount;
                curBottomIndex = (curBottomIndex + content.childCount) - columnCount;
                curTopIndex = curTopIndex % content.childCount;
                curBottomIndex = curBottomIndex % content.childCount;
                curIndex =curIndex - columnCount;
        end
            FreshBackpack();
    end
end

function FreshBackpack()
    local offset = 0;
    for i=1,content.childCount do
        local contentChild = content:GetChild((curTopIndex + i - 1) % content.childCount);
        local textChild = contentChild:GetChild(0);
        if ((curIndex + offset) <= #itemIDs) then
            textChild:GetComponent(UI.Text).text = tostring(itemIDs[curIndex + offset]) ;
            InitializedChildButton(contentChild, curIndex + offset);
        else
            textChild:GetComponent(UI.Text).text = "";
            InitializedChildButton(contentChild);
        end
        offset = offset + 1;
    end
end

function InitializedChildButton(contentChild,index)
    local buttonClickedEvent = Button:ButtonClickedEvent();
            buttonClickedEvent:AddListener(function()
                if (index ~= nil) then
                    table.remove( itemIDs,index );
                    FreshBackpack();
                else
                    print("None Object");
                end
            end);
    contentChild:GetComponent(UI.Button).onClick = buttonClickedEvent;
end

function JumpToTargetID( ID )
    local index;
    for i=1,#itemIDs do
        if ID == itemIDs[i] then
            index = i;
            break;
        end
    end
    if index == nil then
        return nil;
    end

    curIndex = index - (index - 1 ) % columnCount;
    curTopIndex = 0;
    curBottomIndex = initializedBottomIndex;
    local newContentLocalPosY = math.floor( curIndex  / columnCount ) * oneBlockHeight;
    content.localPosition = UnityEngine.Vector2(content.localPosition.x,newContentLocalPosY);
    contentCurTopPosY =content.localPosition.y;

    local curTopRowIndex = (curIndex-1) / columnCount;
    for i=1,content.childCount do
        local rectTransform = content:GetChild(i-1):GetComponent(UnityEngine.RectTransform);
        local newAnchoredPosY = (curTopRowIndex * -oneBlockHeight) + (-oneBlockHeight * math.floor((i-1) / columnCount) - math.floor(0.5 * content:GetComponent(UI.GridLayoutGroup).cellSize.y));
        rectTransform.anchoredPosition = UnityEngine.Vector2(rectTransform.anchoredPosition.x,newAnchoredPosY);
    end

    FreshBackpack();
end


你可能感兴趣的:(Unity-UGUI无限循环列表)