Search Unity

Infinite Scroll with ScrollRect

Discussion in 'UGUI & TextMesh Pro' started by robertohuertasm, Aug 29, 2014.

  1. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi,

    first of all I must confess that I'm an absolute Unity newbie so maybe I'm missing something. I'm playing around with these new UI controls because I want to implement some Wheel Pickers that will be loaded dynamically.

    I'm studying the ScrollRect and I can see that with an unrestricted movement and calculating the content position I could manage to move the items in the collection where ever I need.

    I have tried this approach and it works ok.

    The problem is when I want to know when the animation stops. It seems impossible to get to the velocity. I've decompiled the ScrollRect and implemented one myself in order to expose the velocity but I don't know if there's a better approach in order to accomplish this scenario. I guess you decided to not expose the velocity because of something. Same goes for some events when start dragging, dragging and end dragging. Why they are not there?

    Any help will be really appreciated :D

    Best regards,

    Roberto.
     
  2. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    We'll expose the velocity property.
     
    GibTreaty and robertohuertasm like this.
  3. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Great to hear that!

    One more question about this scenario, which I think can be very common. Imagine I have a list of items scrolling in an infinite manner but I want to disable the dragging just for some of them, i.e: when I start the drag over one specific item, this item is not "enabled" but must be visible?

    Is this already possible? Or any enabled UI element will cause the scroll rect to scroll the content?

    If that's the case maybe it would be nice to expose some OnInitDragging( object sender, DraggingEventArgs e) event before starting dragging with the possibility to cancel the dragging via e.handled or something like this.

    Just thinking out loud about what I may be needing in order to implement such controls.

    Thank you for your time.

    Best regards,

    Roberto.
     
  4. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    I don't really understand what is meant here.
     
  5. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Sorry, I realise my explanation was a bit clumsy. I'll try to rephrase it. I was trying to pose an scenario where the developer could disable the dragging depending on the point it started.

    For what I've seen, the dragging only takes place if there's a UI element as content. What if I would like to have a UI element as content that won't activate the dragging movement? Imagine I have three buttons as content and I don't want the first one to be able to start the scroll but I want it to be visible and active for other purposes.

    Is this currently possible without exposing some kind of event on start dragging? Essentially, this was my question.

    I hope it's clearer now :D

    Kind regards,

    Roberto.
     
  6. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    HI,

    You can do this by implementing the Drag handler on this element. If you do this that element will 'eat' the drag event and not pass it up the chain. In b19 you will also be able to set the drag threshold to something quite high so that the button still 'works' in this case even if you move the pointer a little bit.
     
  7. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi Tim,

    thanks for your answer! I finally got it working and actually that's the way I'm implementing this right now. I found out about how Unity manages some events after posting my latest post. It's not very intuitive but once you know it it's easy to get used to. :D

    Thank you very much for your help and support!!
    Roberto.
     
  8. Deleted User

    Deleted User

    Guest

    Hi Newton,

    Can you give me some insight on how you did the infinite scroll? I'm looking at this right now.

    For now I only want to scroll vertically. When I look at this the Scroll View references the Scroll List (a GameObject with children) and that Scroll List dictates the height (how much it can scroll) so when it gets to the end it's done.

    I'm going to take a shot at this but through script do you move the Scroll List back down by an offset of how much it has moved and then reuse items from the list that are not visible to be the new ones (so scrolling the items up if they have gone too far you shift the list down and reuse the item from the top to be at the bottom with new content).

    -- Hope this makes sense.

    Thanks,
    Will
     
  9. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi Will,

    I use a prefab of two gameObjects. One (Scroll) contains the ScrollRect and my custom script and the other (Content), which is contained by the previous one, is just the one which will contain the items .

    Basically, I move the Content and try to keep the items always in position so when one item gets out from the initial boundaries I move it to the other side.

    I don't know exactly how is your scenario but in my case I use a collection of items and I pass it to my Scroll as a datasource. Then I only draw as many prefabs (you have to create a prefab for the items) as I need to fill the Content area and a little more. Let's say I assume that the Content area = Content Area * 1.5 This way I always have some extra items on the sides in case the animation is quicker than normal.

    You may be wondering, what if I have more items than prefabs in the screen? I manage that internally. I assign the corresponding item to every prefab when they switch sides.

    It's a bit difficult to explain this but the basic idea is the one I explain in the second paragraph.

    I'm still working in my app and polishing the InfiniteScroll control. I'm planning to sell it in the Assets Store once I finish it but I can help you if you need more specific guidance.

    Best regards,

    Roberto.
     
  10. Deleted User

    Deleted User

    Guest

    Hi Roberto,

    Thanks for getting back to me! To give you an idea I am making a Friends List Selector for Facebook and will have to handle cases where people have too many friends. I figured the best way was to get the list of friends from FB and then populate a count that fit in my window. The user scrolls and as they do I cycle the items that go off (similar to what you are saying I believe).

    If I were looking at the Hierarchy it should look something like this:
    • Canvas
      • Game Object with a Scroll Rect that uses Foo as the Content and the Custom Script
        • Game Object Called Foo that is the Content used in Scroll Rect
          • Content Item
          • Content Item
          • ....
    From working with the Scroll Rect already I found that the Scroll Rect needs a Content and a size so it can scroll it, is this true? Or wait (Lightbulb....) you have the Scroll Rect set to Unrestricted and can cycle them that way (how did I miss this, I should have made it from start and not try to use what I already have); is this the correct way?

    Thanks,
    -- Will
     
  11. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi Will,

    I forgot to tell you. Your intuition is correct. I set it to unrestricted so I can move the Content (Foo) anywhere and I cycle over my prefabs.

    Best regards,

    Roberto.
     
  12. umangdesai

    umangdesai

    Joined:
    Jul 9, 2013
    Posts:
    3
    Hi, Newton_W

    I am also trying to make a similar kind of Infinite scroll. But i have only 3 items in it.Can you explain a lil bit more about how you are achieving this??
     
  13. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi umangdesai,

    depending on the size of the items you can calculate how many of them will fit into the scroll area. ç

    Let's say that you calculate that in your scroll area you can put 3 items. What I do is to always multiply this number x 1.5 so you will end up having more prefabs on both side of the scroll area. You will have to fill this prefabs with your 3 items and certainly they will get repeated.

    This way, if you only have 1 item and the scroll area is huge you can achieve also an infinite effect.

    Hope it helps.

    Best regards,

    Roberto.
     
  14. anamoutinho

    anamoutinho

    Joined:
    Jul 23, 2013
    Posts:
    1
    Hi Roberto,

    You mentioned that you're thinking of selling your infinite scroll control on the Assetstore, do you have any prevision when? I would be very interested on that, even if is not a final version.

    Thanks,
    Ana
     
  15. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi Ana,

    first of all, sorry for my late answer. At the moment I have no real prevision of when it will be. I'm using it right now in a production app and it works but I'm not sure that I've covered all the cases yet.

    Could you explain to me what exactly are you trying to put inside the spinners? My control accepts a datasource and a prefab which is used to bind data against, so all elements on the spinner will be of the same kind. It's up to you to build the prefab to adopt different behaviours or show something different depending on each data item.

    I'm a bit busy this week but I'll try to prepare a first version. I can't promise you a fixed date though.

    If you want you can email me at roberto.huertas[at]outlook[dot].com

    Best regards,
    Roberto
     
  16. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi, I've already published the InfiniteScroll extension at http://u3d.as/b9m

    Roberto.
     
  17. JohnTube

    JohnTube

    Joined:
    Sep 29, 2014
    Posts:
    66
    Hi @Newton_W

    I have few questions regarding your implementation if I may :
    • Do you use a LayoutGroup and ContentSizeFitter in the content container object ?
    • Does your implementation support adding Items (one by one) on the fly to list or it need the whole list as DataSource from the beginning ?
    • And why do you need a Box Collider in the list item prefab to detect input events ?
    • The video of the Monk app shows that list views "snap" to children. Is it supported in the asset by default ?
    The first two questions are important to me as I started my own implementation and I faced a problem of moving items from top (first sibling) to bottom (last sibling) and vice versa. I'm just changing the item's sibling index in the container's transform which leads to an automatic rearrangement (reordering and re positioning) due to the LayoutGroup and ContentSizeFitter. If disabling those components after populating the list, or even getting ridding if them won't help maybe I need to put the whole list in its own canvas having its own camera and move the camera instead.

    I'm also using the ScrollRect's OnValueChanged event to detect direction and number of items that went "invisible" (out of mask boundaries). It's not very intuitive because the Vector2 argument that is supposed to give the new position/coordinates is not much of a help, do you think I need to find another (better cleaner) way to do it ?
     
  18. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44
    Hi @JohnTube ,

    • No, I don't use LayoutGroup or ContentSizeFitter anywhere.
    • It supports dynamic addition and substraction.
    • It's the way I can get where the selected item is placed.
    • I'm not sure to understand what you say here but everything you see in the video is supported by default.
    I'm not using OnValueChanged for the moment but maybe is a good way to get direction changes.

    Best regards,
    Roberto.
     
  19. IvovdMarel

    IvovdMarel

    Joined:
    Jun 1, 2014
    Posts:
    9
    I created a (quite basic) version of an infinite ScrollRect right here. It's free, and comes with a demo scene.

    I used the HorizontalLayoutGroup, VerticalLayoutGroup and ContentSizeFitter.

    https://github.com/ivomarel/InfinityScroll

    I just made it this morning so I'm expecting to make some more changes in the near future
     
    DungDajHjep, JohnTube and GibTreaty like this.
  20. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    201
    Thanks you very much !
     
  21. blamejane

    blamejane

    Joined:
    Jul 8, 2013
    Posts:
    233
    Thanks @IvovdMarel great script and video!!

    How can I make the InfinityScroll script "snap"? I want the button elements (which is what I have on my scroll panel) to snap to center of screen. Basically there buttons swipe horizontally and whichever button is closest to the center will then snap so that it's directly in the center.
     
  22. fafase

    fafase

    Joined:
    Jul 3, 2012
    Posts:
    163
    Basically, you could take the position of each child of the ScrollRect and figure out which is closer to the center position. Then take the distance between the center and the closest item and move the scroll rect position by that value.

    Code (CSharp):
    1. Transform closest = FindClosest(centerPoint.position, arrayOfChildren);
    2. float xDelta = centerPoint.position.x - closest.position.x;
    3. Vector2 v = rt.anchoredPosition;
    4. v.x += xDelta;
    5. rt.anchoredPosition = v;
     
  23. ankitgoel

    ankitgoel

    Joined:
    Jan 3, 2013
    Posts:
    9
    Hey @IvovdMarel thanks for the scripts, however when i try to populate the elements dynamically Unity freezes, every-time, is there something i am missing here.
     
  24. ankitgoel

    ankitgoel

    Joined:
    Jan 3, 2013
    Posts:
    9
    @Newton_W Is your plugin Unity 5 compatible ?
     
  25. robertohuertasm

    robertohuertasm

    Joined:
    Aug 29, 2014
    Posts:
    44