Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A bug that dynamically adds Cells in GridLayout that does not show Cells in certain situations #178

Open
suhyunrim opened this issue Aug 6, 2024 · 3 comments

Comments

@suhyunrim
Copy link

suhyunrim commented Aug 6, 2024

Hello. I'd like to ask you about two issues.

  1. GridLayoutGroup is adding cells over time. If the cells overlap the Viewport size here, the second cell from that line will not be seen. Add the following code to InitOnStart and it will be reproduced in DemoSceneSingle. Please refer to the video.
        private float elapsedTime = 0;
        private void Update()
        {
            elapsedTime += Time.deltaTime;

            if (totalCount < 50 && elapsedTime >= 0.1f)
            {
                elapsedTime = 0;
                totalCount++;

                var scrollRect = GetComponent<LoopScrollRect>();
                scrollRect.totalCount = totalCount;
                scrollRect.RefreshCells();
            }
        }
_2024_08_06_21_37_22_211.mp4
  1. Following Logic 1, Cells were added to add a logic that scrolls when it exceeds the Viewport size. This solves Issue 1 (not a fundamental solution), but creates an issue that Cells are not recycled. Likewise, add the following code to InitOnStart and reproduce it in DemoSceneSingle. Please refer to the video.
        private float elapsedTime = 0;

        private void Update()
        {
            elapsedTime += Time.deltaTime;

            if (totalCount < 50 && elapsedTime >= 0.1f)
            {
                elapsedTime = 0;
                totalCount++;

                var scrollRect = GetComponent<LoopScrollRect>();
                scrollRect.totalCount = totalCount;
                scrollRect.RefreshCells();
                if (totalCount % 4 == 1)
                    scrollRect.ScrollToCellWithinTime(totalCount - 1, 0.5f);
            }
        }
_2024_08_06_21_38_02_894.mp4
@qiankanglai
Copy link
Owner

Hi,

Thanks for detail report! This is a common API misusage:

  • RefreshCells is designed for refresh item data only (with totalCount fixed)
  • RefillCells is designed for chaning totalCount

so the test code should be like:

private float elapsedTime = 0;
private void Update()
{
    elapsedTime += Time.deltaTime;

    if (totalCount < 50 && elapsedTime >= 0.1f)
    {
        elapsedTime = 0;
        totalCount++;

        var scrollRect = GetComponent<LoopScrollRect>();
        scrollRect.totalCount = totalCount;
        float offset;
        var start = scrollRect.GetFirstItem(out offset);
        scrollRect.RefillCells(start, offset);
    }
}

This refills cells while keeping the first item and offset visually nochange.

@suhyunrim
Copy link
Author

Thank you for your reply!

I was referring to the "UI_ControlData.OnButtonAddDataClick" demo code.

        private void OnButtonAddDataClick()
        {
            int AddCount = 0;
            int.TryParse(m_InputFieldSrollToCell_AddCount.text, out AddCount);

            int TargetCount = Mathf.Max(1, AddCount);
            for (int i = 0; i < TargetCount; ++i)
            {
                int RandomResult = Random.Range(0, 10);
                m_ListBank.AddContent(RandomResult);
            }

            m_InitOnStart.m_LoopScrollRect.totalCount = m_InitOnStart.m_LoopListBank.GetListLength();
            m_InitOnStart.m_LoopScrollRect.RefreshCells();
        }

Anyway, I would like to add new items (=new data) at the end of the scroll in very short time intervals.

However, the "RefillCells" function returns all the items you are currently seeing to the Pool and gets them again, calling the "ProvideData" function of all the items again.

Just to give you an example of my situation, I have about 60 items that can be seen in scrolling (there's a lot more data) and I add one every 0.02 seconds. Then it works like below.

0.02 seconds -> Call the first item "ProvideData"
0.04 seconds -> Call the first and second item "ProvideData"
0.06 seconds -> Calling the first, second and third items "Provide Data"

All I'm looking forward to is adding a new item at the end, only the "ProvideData" function of the last item needs to be called.

I would appreciate it if you could tell me if there was anything I misunderstood or any other solution.

And I'm sorry for my clumsy English.

qiankanglai added a commit that referenced this issue Sep 7, 2024
@qiankanglai
Copy link
Owner

Hi,

The use case you provided is quite practicable so I fixed with GridLayout may increase totalCount at any time, so fill last row when possible.
Now you can safely call RefreshCell with GridLayout.

BTW, even through pool operations are skipped with RefreshCells, ProvidedData is stll invoked in every refresh. You can just cache last index and skip unnecessary ones.

LoopScrollRectDev.-.DemoScene.-.Windows.Mac.Linux.-.Unity.2021.3.33f1.Personal_._DX11_.2024-09-07.16-29-53.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants