Giter Club home page Giter Club logo

loopscrollrect's Introduction

Loop Scroll Rect

openupm License: MIT

These scripts help make your ScrollRect Reusable, because it will only build cells when needed. If you have a large number of cells in a scroll rect, you absolutely need it! It will save a lot of time loading and draw call, along with memory in use, while still working smoothly.

中文说明请看这里

Installation

Open Package Manager and Add package from git URL https://github.com/qiankanglai/LoopScrollRect.git.

With OpenUPM, just one command openupm add me.qiankanglai.loopscrollrect.

With older Unity version, just clone the repo and put into Assets/.

Demo

Demo for Loop Scroll Rect. Each cell knows its own index, and it is able to modify its content/size/color easily.

Also ScrollBar is supported now! It supports both vertical & horizontal directions, back and forth.

Demo1

Demo2

Demo without mask. As you can see, the cells are only instantiated when needed and recycled.

Demo3

New: Scroll to Index

ScrollToIndex

Introduction

The original idea comes from @ivomarel's InfinityScroll. After serveral refactorisations, I almost rewrite all the codes:

  • Avoid using sizeDelta directly since it doesn't always mean size
  • Support GridLayout
  • Avoid blocking when dragging back
  • Take advantage of pool rather than instantiate/destroy every time
  • Improve some other details for performance
  • Supports reverse direction
  • Supports ScrollBar (this doesn't work in Infinite mode, and may behavior strange for cells with different size)

My scripts copies ScrollRect from UGUI rather than inherit ScrollRect like InfinityScroll. I need to modify some private variants to make dragging smooth. All my codes is wrapped with comments like ==========LoopScrollRect==========, making maintaining a little easier.

Example

Please refer to InitOnStart.cs for quick example implmentation. It's high recommended for implmentating your own cache pool.

Infinite Version

If you need scroll infinitely, you can simply set totalCount to a negative number.

Quick Jump

I've implemented a simple version with Coroutine. You can use the following API:

public void SrollToCell(int index, float speed)

Here is a corner case unsolved yet: You can't jump to the last cells which cannot be pulled to the start.

Example: Loop Vertical Scroll Rect

These steps may be confusing, so you can just open the demo scene and copy & paste :D

You can also remove EasyObjPool and use your pool instead.

  • Prepare cell prefabs
    • The cell needs Layout Element attached and preferred width/height
    • You should add a script receiving message void ScrollCellIndex (int idx)

ScrollCell

  • Right click in Hierarchy and click UI/Loop Horizontal Scroll Rect or UI/Loop Vertical Scroll Rect. It is the same for these two in the Component Menu.
    • Init in Start: call Refill cells automatically when Start
    • Prefab Pool: the EasyObjPool gameObject
    • Prefab Pool Name: the corresponding pool in step 1
    • Total Count: How many cells are available (index: 0 ~ TotalCount-1)
    • Threshold: How many additional pixels of content should be prepared before start or after end?
    • ReverseDirection: If you want scroll from bottom or right, you should toggle this
    • Clear Cells: remove existing cells and keep uninitialized
    • Refill Cells: initialize and fill up cells

LoopVerticalScrollRect

If you need scroll from top or left, setting content's pivot to 1 and disable ReverseDirection. Otherwise, you should set 0 to pivot and enable ReverseDirection (I have made VerticalScroll_Reverse in the demo scene as reference).

I highly suggests you trying these parameters by hand. More details can be found in the demo scene.

loopscrollrect's People

Contributors

codingfishwu avatar qiankanglai avatar roointan avatar syaoranchang avatar tuanpm62 avatar zxsean avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loopscrollrect's Issues

Namespace conflicts

Thanks for this - just wanted to give a heads up that there is no namespace for some of these files i.e. EasyObjectPool.cs

: )

滚动条问题

好奇怪,我动态加入 item 到 content下,如果绑定 滚动条控件,数量一多就卡暴了?怎么回事呢?但如果没有绑定滚动条,一切都正常。

网格的时候,格子大小问题

当使用 GridLayoutGroup 时,一下代码有问题。或导致拉动的时候一直抖动
protected override float GetSize(RectTransform item)
{
return LayoutUtility.GetPreferredHeight(item) + contentSpacing;
}
因为用的是GridLayoutGroup ,所以格子的大小应该要从mLayout中获取
修改如下“:
GridLayoutGroup mLayout;
protected override float GetSize(RectTransform item)
{
// return LayoutUtility.GetPreferredHeight(item) + contentSpacing;
return GetCellSize(item) + contentSpacing;
}
float GetCellSize(RectTransform item)
{
if (mLayout != null)
{
return mLayout.cellSize.y; //水平的这边用x
}
return LayoutUtility.GetPreferredHeight(item);
}

Unable to locate Instantiation source of prefabs

I have a custom prefab, which contains a Image element and a text element. I want to have each prefab instance a different name and image which will be updated using a lists with a custom method, however right now prefabs instantiate as soon I press the play button.
Can you give some direction to achieve this?

How to know when LoopScrollRect setup completed?

Dear,

Because I must do animation (use DOTween) with cells after all cell is filled to scroll view completed,
I tried to do this when function RefillCells completed but it seems not working.

Could you let me know when scroll view is completed initial?

Thanks.

Use with my own pool

When I trying to replace included Pool with simple Instantiate/Destroy ScrollRect is going crazy :)
Later I want to use Adapter to simply integrate any pooling manager, like Zenject etc.

Any advice?
Thanks!

格子控件问题

当格子的每行个数为4的时候,如果初始格子为3个,后面修改为50 个或者更多。超过一屏。
这时候,会发现格子数量有问题。
tmp

Trying to remove **** from rebuild list while we are already inside a rebuild loop. This is not supported.

Probably related to #6 to be appearing on Unity 5.6 again. Even for normal ScrollRect seems.

I'm getting this error about 24 times when I start the game. If I remove references to Horizontal and Vertical Scrollbars. I only get 1 of them. But the scrolling doesn't work properly jumps around a lot and still seems to update scrollbars even tho they are not assigned in editor.Trying to remove LogRow(Clone) (UnityEngine.UI.Text) from rebuild list while we are already inside a rebuild loop. This is not supported.

image

Trying to remove LogRow (UnityEngine.UI.Text) from rebuild list while we are already inside a rebuild loop. This is not supported. UnityEngine.GameObject:SetActive(Boolean) Pool:AddObjectToPool(PoolObject) (at Assets/Plugins/Internal/ScrollRectLoop/EasyObjectPool/EasyObjectPool.cs:72) Pool:ReturnObjectToPool(PoolObject) (at Assets/Plugins/Internal/ScrollRectLoop/EasyObjectPool/EasyObjectPool.cs:153) ResourceManager:ReturnObjectToPool(GameObject) (at Assets/Plugins/Internal/ScrollRectLoop/EasyObjectPool/ResourceManager.cs:109) UnityEngine.UI.LoopScrollRect:LateUpdate()

小建议

首先先谢谢你的功能。学习了一波。
不过有个地方,或许还可以有一点改进。
有时候需要增加的按钮,并不会做成单独的预制体,可能只是某个预制体的子按钮。
只想clone一下,你却写死了只能通过Resource的方式去加载。

Trying to remove base_model (UnityEngine.UI.Image) from rebuild list while we are already inside a rebuild loop. This is not supported.

Trying to remove base_model (UnityEngine.UI.Image) from rebuild list while we are already inside a rebuild loop. This is not supported.
UnityEngine.GameObject:SetActive(Boolean)
UnityEngine_GameObjectWrap:SetActive(IntPtr) (at Assets/ToLuaGenerate/UnityEngine_GameObjectWrap.cs:296)
LuaInterface.LuaDLL:lua_pcall(IntPtr, Int32, Int32, Int32)
LuaInterface.LuaState:PCall(Int32, Int32) (at Assets/LuaFramework/ToLua/Core/LuaState.cs:632)
LuaInterface.LuaFunction:PCall() (at Assets/LuaFramework/ToLua/Core/LuaFunction.cs:91)
UnityEngine.UI.LoopScrollRect:LateUpdate()
unity版本5.4.3
出现问题的情况 是我操作克隆出来的item 里面的元素 隐藏里面的image 就会出现这个错误

ResourceManager发现一处游戏对象未销毁

resourceManager 的InitPool方法里,创建了一个 gameObject, 供对象池做预设,但是最后没有销毁掉,导致场景中多了一个无用的游戏对象,可以在对象池初始化完毕后,销毁掉该对象

Refill on start doesn't work consistently

Refilling scroll rect on start is not consistent.
ScrollRect sometimes is populated on start and sometimes it is not.

I looked at demo and noticed in your examples 1st VerticalSCroll object get's auto populated on start, others require InitOnStartScript. It becomes even more confusing due to the fact that both scrolls VerticalScroll and VerticalScroll_Reverse have exactly the same properties in inspector (apart of Reverse Direction toggle.

iOS issue

Crash on transitioning between scenes with LoadSceneAsync.
Transitioning between scenes without these components do not crash.

Several loads are required to crash the app.

Any idea what this could be? Great component nonetheless.

Cumps

可移植性替换方案

在LoopScrollRect的'ReturnObjectAndSendMessage'方法中,用到了ResourceManager,这里有点耦合,如果有自己的对象池实现方法,不用例子里自带的这个ResourceManager,这里会报错.发现获取对象池里的对象是通过LoopScrollPrefabSource这里拿的,那么也可以把对象回收方法也交由这个类来执行,那么ReturnObjectAndSendMessage这里就可以使用prefabSource的回收对象池方法了.一点建议,这个库还是挺好用的!

ScrollToCellCoroutine函数中else中计算offset有误

if (directionSign == -1)
offset = reverseDirection ? (m_ViewBounds.min.y - m_ItemBounds.min.y) : (m_ViewBounds.max.y - m_ItemBounds.max.y);
else if (directionSign == 1)
offset = reverseDirection ? (m_ItemBounds.max.x - m_ViewBounds.max.x) : (m_ItemBounds.min.x - m_ViewBounds.min.x);
上面这段代码计算有误 会导致参数index = totalCount - 1时 needMoving不能置为false 。应该是min和max写反了,我修改后就没有问题了。
另外大佬能否添加一些content的滑动进度和添加一些content滑动结束的事件回调,现在有这样的需求都是自己添加。谢谢

新功能建议

1、建议增加一个Snap To Grid选项,使每次拖拽结束之后都会慢慢停到某个格子开始的地方
2、建议增加一个ScrollToItemAnimated方法,用于以一定的速度滚到某个格子

cell点击事件如何传递到控制器

我们使用的是MVC结构,有个主控制器脚本,控制页面上所有UI元素,所有UI逻辑跳转都在这里处理,然后在cell上也绑定了一个脚本,用于控制该cell的显示,然后点击cell时,需要将点击事件传回给控制器,并告知下标,请问这个该如何实现,你的Demo中也没有这个功能.另外,如果我要设置某个cell的高亮状态,这个也没办法实现,希望下个版本能增加这个功能,谢谢!

HELP ME...

.
When i use your plugin. I got error:
Trying to remove myImage (UnityEngine.UI.Image) from rebuild list while we are already inside a rebuild loop. This is not supported.
UnityEngine.GameObject:SetActive(Boolean)
MyClass:ScrollCellIndex(Int32)
UnityEngine.UI.LoopScrollRect:LateUpdate()

how to fix this, please..

Change element appear?

Man!
Sorry if i post in wrong place, I'm a newbie and have a question, hope that you can help :D. I'd like to make the list appear like zoom or scale it when drag and it become normal size when stop. What is the idea to make this. Thanks for your help?

Cell中点击事件错乱

你好,在使用中出现了以下问题:
在Cell中加入一个Button,滚动列表,然后点击任一Cell中的button,会发现点击事件会被调用多次,而且顺序错乱。
Cell 11is Clicked
Cell 24is Clicked
Cell 37is Clicked
Cell 25is Clicked
Cell 11is Clicked
...
请教这个如何解决,谢谢!

Refill后导致ScrollBar计算出错一直闪烁

1、使用Github的DemoScene
2、其他的ScrollView都SetActive(false)只留下VerticalScroll做实验
3、运行场景,点击Clear,把初始化的50个干掉,把VerticalScrollBar设置为AutoHideAndExpandViewport,填TotalCount为12,点Refill复现

LoopHorizontalScrollRect with GridLayoutGroup and row count > 1

Hello.

Can you please adapt your LoopScrollRect for using with horizontal GridLayoutGroup when "Fixed Row Count" > 1?

Example (short video):
https://gfycat.com/FatherlyWealthyAtlanticblackgoby

How to reproduce on demo project:

  1. Replace "Horizontal Layout Group" with "Grid Layout Group" in content of "HorizontalScroll" gameobject.
  2. Set "Constraint" to "Fixed Row Count".
  3. Set "Constraint Count" to 2 (or more).
  4. Run project.
  5. Try to scroll and take a look on cell numbers.

RefillCellsFromEnd 定位和滚动问题

实际需求中经常要插入之后,定位在列表的最后一个,发现两个问题:

  1. RefillCellsFromEnd 接口不能很好让列表滚动到最后一个,不知道是不是位置计算问题
    image
    修改之后Ok
  2. RefillCellsFromEnd 使用之后很大的概率很产生向上的的滚送(m_Inertia开启), 估计是因为后面lateupdate的计算认为这是一个下拉的操作吧,我处理方式比较死,在这个函数最后 等待一帧,停止滚动
    image

这里应该可以有更好的方式处理,

kanglai同学不知道能否从更好的方式优化下或者说本身我就在错误的方式使用?

添加EventTrigger组件之后无法滑动

你好!最近在使用的时候,需要在cell上添加EventTrigger组件,结果无法滑动了,查了下,原因是EventTrigger继承了Drag的几个接口,导致LoopScrollRect里的Drag方法无法接受监听,那么有什么方法解决呢?谢谢!

ContentSizeFitter and grid performance issue.

Using Content size fitters and grid layout groups together with scroll rect or loopscroll results in the UI Updating all the time. Even when nothing in the UI changes/the scroll doesn't move. Disabling the content size fitter resolves this issue but then scrolling doesn't work as intended anymore. I tried to make the scrolling work without a content size fitter, but I didn't manage to pull it off.
profilergraph
profilerdata

Is there a way to use loopscroll with a grid and without a content size fitter?

Scrollbar(Bug)

Hi!How to use it?It considers all the elements and not only those which are visible on the screen,
Scrollbars should depend on the total Count

初始化单元格不全

你好,使用中出现了一个问题,就是初始化的时候始终只初始化一半的界面,然后只要轻轻一碰单元格,剩余的就刷出来了,请问有可能是什么原因?

default
1

LoopHorizontalScrollRect在特定条件下存在兼容性问题

我使用LoopHorizontalScrollRect,布局使用
111

请注意我红框里的设置

在这种情况下显示会不正确,第一次加载的时候明明有4条数据,但是只能显示一个出来,显示区域是可以足够显示全部4个的。拖动一下就4个都显示了。

我将 Horizontal Layout Group 换成 Grid Layout Group ,使用相同的布局设置,却不会出现这个问题。

Problem with scroll

I use dynamically filled horizontal list, update DataSource and scroll to need position. But the scroll does not behave correctly!
Using a demo it can be shown so:

public class InitOnStart : MonoBehaviour
{
    void Start()
    {
        var loop = GetComponent<LoopScrollRect>();
        loop.totalCount = 5;
        loop.RefillCells();
    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.Space)) {

            var loop = GetComponent<LoopScrollRect>();
            loop.totalCount += 10;
            loop.RefillCells();
            loop.horizontalNormalizedPosition = 1;
        }
    }
}

Afte press Space, List increase size to 15 elements, scroll to end, and immediately scroll to begin!! Why scroll to begin? I set horizontalNormalizedPosition to 1 that should be end of list!

here it works correctly:

public class InitOnStart : MonoBehaviour {
    private int count = Int32.MaxValue;

    void Start() {
        var loop = GetComponent<LoopScrollRect>();
        loop.totalCount = 5;
        loop.RefillCells();
    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.Space)) {
            var loop = GetComponent<LoopScrollRect>();
            loop.totalCount += 10;
            loop.RefillCells();
            count = 0;
        }
        if (count < 3) {
            GetComponent<LoopScrollRect>().horizontalNormalizedPosition = 1;
            count++;
        }
    }
}

But if change condition to if (count < 2) - not work). For more items need more count.
what happen??

求问能否将Easy Object Pool替换成PoolManager?

我尝试将Easy Object Pool替换成PoolManager,但是发现在将上下超范围的item返回池中时(这个动作在poolManager,我使用spawnPool.Despawn),索引会发生错乱,能否在这个问题给我一些帮助?

Custom Pool Size

Hi.
I have adjusted the pool size, but it does not works.
For example, I wanted 8 objects to be pre-created and use them as pool, but there is only two.
How can I get custom pool size working?
Thanks.

发现一个疑似Bug的情况,详情如下

正在做的需求是一个聊天,收到一条消息settotalcount,这样totalcount会每次加一,然后设置verticalNormalizedPosition缓动到1,这个时候会去检测顶部的item是否可以删除,检测viewBounds.max.y < contentBounds.max.y - threshold时为true,进入删除的时候有个判断(totalCount >= 0 && itemTypeEnd >= totalCount - 1)这里true了,导致顶部item一直删不掉。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.