Search Unity

Optimized ScrollView Adapter + Playmaker support

Discussion in 'Assets and Asset Store' started by xucian, Apr 1, 2016.

  1. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Hi here again =) How i can implement dinamic state of elements ? User case : click on track in playlist, it starts loading, show progress bar etc, user can scroll list, return to loading track and must see it'a actual progress.
    I handled almost all of this stuff (code https://pastebin.com/XPRXev10), but have an issue : after beggining of loading if you very fast scroll list, element loosing it's visual actual state(progress bar progress an so on). In editor i see that code is now pointing to the element that not visible now and has the same variables values as out target (i.e copy).

     
  2. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hi,

    Once you get used to the fact that the views are recycled and you shouldn't store any data in them, you'll achieve greatness :D
    Anything that should be preserved after the item goes out of view, should be stored in your model. The views are constantly recycled and they usually retain the old data unless you manually clean them before updating them with new data

    Did this answer your question?

    Best,
    Lucian
     
  3. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    I store in model logical vars like loaded, loading, progressValue. Should i store there links on visual elements too?

    I noticed that if i scroll list a little bit to call all CollectViews(), then all works fine. If not, then can catch my issue
     
    Last edited: Apr 19, 2018
  4. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    What do "links on visual elements" mean?
     
    justtime likes this.
  5. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Link on Text element of prefab and so on. Seems that if not all CollectViews() was called, i start loading track, scroll down to hide it, scroll up again, and due to CollectViews() call, now model changing visual components of another element. So it changing 2 components. May be i'am shoudnt using BaseParamsWithPrefabAndLazyData ?
     
  6. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    The "LazyData" part was provided for cases when you don't want to retrieve all the models at once (but there are other ways to achieve this, of course). This is useful when your data comes from an offline source (local storage).
    If your models come from an online source or if you simply load all of the items at once (I'm guessing you're retrieving all of them at once, even though the actual audio stream is downloaded only after you press the play button on an individual item), you can use the BaseParamsWithPrefabAndData, which simply uses a plain C# List to store your models.

    Did this help?
     
  7. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    I can't handle how to save the model state in loading Coroutine.
    I have
    Code (CSharp):
    1. while (progress < 1)
    2.         {          
    3.             progress += 1 / speed * Time.deltaTime;
    4.             progressBar.SetProgress(progress, false);
    5.             model.loadingValue = progress;
    6.             yield return Timing.WaitForOneFrame;
    7.         }
    8.  
    So if i scroll list before loading anything, all CollectViews was called, and this is works fine, but if not, then when i start loading first element , scroll to hide it, then return, and in this moment my loading coroutine unpdating another progressBar, while model the same
     
  8. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hmm, while this is outside the plugin's scope (it's specific to your implementation, not the plugin itself), here's my suggestion:
    Inside MonoBehaviour.Update, constantly update the visible items' progress bars. This will assure you're always having up-to-date progress bars. There are multiple ways of getting the currently visible items (the "views holders"). After that, you can access their ItemIndex, through which you'll access their associated model, from which you'll get the progress bar's value.
    It's normal to get tricky, because this item loading paradigm inside scrollviews is a universal problem and it's not that easy to get done right from the start.
    My solution removes the dependency on the views. Your data fetching code will only update a model. And the views will access that model whenever they want (in our case, the progress bar will be updated in each MonoBehaviour.Update and the rest of the data, which is constant, will be updated in UpdateViewsHolder, as usual).
    Don't forget to call base.Update().

    Hope that made sense
     
  9. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Thanks a lot! Your advice really helped me solve the problem =)
     
    Last edited: Apr 20, 2018
  10. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Yes :)
     
  11. MohHeader

    MohHeader

    Joined:
    Aug 12, 2015
    Posts:
    41
    Hi :)

    Thanks for the asset,, Great one.

    Just wondering if flexible grid layout ( same as Unity's GridLayout ) is in your plans to support ?

    Thanks again
     
  12. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hi,
    Thanks! :)

    This is already on our to do list, but won't be implemented very soon, because the next release will be a major upgrade to the plugin's core optimizer and only after we'll make sure that works seamlessly can we start devouring the "new features" to do list
     
  13. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
  14. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    Does this asset support a variable number of horizontal cells in the GridView in the latest version? I can't get a clear answer on this.

    Specifically, if the GridView is resized, can the script automatically increase the number of cells it is putting into each row?
     
  15. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    @thefallengamesstudio
    hi there, your scrollview looks amazing, however few missing things which another competitor have
    1-You have good pull to refresh, but not pull up to load more example
    2- didnt see any responsive grid view
    3- based on 1 and 2 , a responsive grid view with both pull to refresh and pull up to load more
    4- scrolling start and scrolling end events
    5- page view is good, but only 1 page should scroll in one mouse action. For example if load ur web glexample, on a wide monitor, and hold dowd and start moving, it atleast show 3-4 pages before im no more able to scroll. Which means its very bad for performance, and not right approach. Right approach is only show 1 page at a time (so maximum 3 and minimum 2 recycleable items). in short, if i want to view 3 pages, i have to scroll 3 times no matter the wide moniter.

    If you can provide these, ill buy yours.
    Thanks
     
  16. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    I successfully implemented a flexible grid layout using your existing component.
     
  17. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hi, this is a side-feature, but it's already in the to-do list. Will take aome months before the next version will be uploaded.

    Edit: Glad to hear you implemented it yourself! Happy coding :)
     
  18. symbell

    symbell

    Joined:
    May 19, 2013
    Posts:
    7
  19. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hi, I have no access to the link provided. I sent a request for access.
    2-way scroll can be implemented using a second scrollview as a parent (it doesn't need to be with SRIA attached - just a plain scrollview). This would be a first approach, but it depends on what your exact requirements are. Send me an email when you have granted me access to the image
     
  20. symbell

    symbell

    Joined:
    May 19, 2013
    Posts:
    7
    I've accepted the permission and also send the source code via email, please have a look and let me know at the earliest.
     
    xucian likes this.
  21. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Hi there! How i can check visibility of the current scroll element ?
    Thanks!
     
  22. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey,

    Look for GetItemViewsHolderIfVisible that checks by itemIndex or GetItemViewsHolder that checks by viewsHolderIndex - which goes from 0 to <the number of currently visible viewsHolders(i.e. items actually visible)> which is stored in _VisibleItemsCount
     
  23. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Hi there! Can i expand items by dynamic expand factor ? So each item can become different size
     
  24. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey,

    Yes, but you need to code it yourself. ~90% of the work is already done in the ExpandCollapseOnClick utility script, so you can copy most of the code from there when writing your script.
    It's not straightforward, as with non-expandable examples, but you can consult the scripts that use this functionality and learn its usage. SimplePullToRefresh is the simplest that uses the expand\collapse functionality.

    Let me know of your progress :)
     
  25. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    I can't handle one thing. My prefab it's a conteiner with Content Size Fitter, and it's total height depending on children sum height. I am just showing some desc Text on click. It seems working but container jerks up down on open.
    My solution is totally like in example, but i am changing preferredHeight of desc Text while opening to achive accordion effect.
     
  26. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey,
    Please check the contentsizefitter example, as you're not allowed to set the items' heights manually (you need to do it through the adapter). Proceed exactly as there (script + setting the prefab's layout exactly as in the example scene - of course you can have any number of ui elements inside the prefab, but the overall format should be the same). The instructions doc also supplements the example scenes with how it all works at a high level

    Let me know of your progress
     
    justtime likes this.
  27. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Thanks! Which param should i use in this line ?
    Code (CSharp):
    1. foreach (var model in _Params.Data.AsEnumerableForExistingItems)
    2.             model.HasPendingSizeChange = true;
    AsEnumerableForExistingItems is aviable only for BaseParamsWithPrefabAndLazyData, but i'am using BaseParamsWithPrefabAndData.
     
  28. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey,
    Good question! Just use Params.Data to traverse all models, since they're all initialized at once.

    The 'lazy' version exposes the 'AsEnumerableForExistingItems' to return all the non-null models, just because the items which have not yet been visible have a null model anyway (it's created first time you access it through LazyList's [ ] operator)
     
  29. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    Thanks. I am missed a little. Please, clear it last time : i need refer to contentsizefitter example ExpandCollapseOnClick ?
     
  30. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    ExpandCollapseOnClick is a totally different script that's used in the exwmple scenes to expand\collapse an item's size through a tween animation.
    I think this script is not present in the CSF example, anyway, so don't bother with it.
    Just follow\copy the steps from the CSF script and scene and let me know of any difficulties you find.
    Shoot me an email with your code if you'll get really stuck and will need more assistance
     
  31. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    In CSF i've added Button to Icon1Image of ItemPrefab, changed LayoutElement of Icon1Image to MinHeight and MinWidth to 20, and changed HorizontalGroup to Vertical of ItemPrefab with same settings.
    Here the code https://pastebin.com/T1cu5aLy.
    I've added event on Button click on which i call
    Code (CSharp):
    1. instance.onButtonClick.AddListener(() => { RebuildLayoutDueToScrollViewSizeChange(); });
    My goal is to show text on image click and recalculate list. So it's recalculating on resize, but i want on click. It works, but sometimes on click item changes it's position, and it's returns only on list resize.
     
  32. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Thanks for being specific about the exact steps you've made to reproduce the issue!

    What I noticed now is: if you're planning to enable/disable game objects inside the CSF, then keep then disabled initially (in the prefab) if they'll immediately be disabled anyway in the first frame after Init (and vice-versa: any GOs enabled by default in the adapter's code, also keep them initially enabled in the prefab also), because otherwise the adapter can't initialize correctly.
    I'll add this in the next small update's Instructions file.

    Apart from disabling the TitleText in the prefab, here's what I've changed in code to make it work:

    In the CreateViewsHolder():
    Code (CSharp):
    1.  
    2.             instance.showButton.onClick.AddListener(() => OnItemClicked(instance));
    Created method:
    Code (CSharp):
    1.         void OnItemClicked(MyItemViewsHolder vh)
    2.         {
    3.             var model = _Params.Data[vh.ItemIndex];
    4.             model.expanded = !model.expanded;
    5.  
    6.             // No need to set HasPendingSizeChange=true, since the rectTransform will be updated immediately
    7.             vh.UpdateExpandedState(model.expanded);
    8.  
    9.             // If you're enabling/disabling children that can have an impact on the item's size (as opposed to just changing their content - like the Text.text property),
    10.             // this is he only reliable way of dynamically changing an item's size through SRIA v3.2 or lower.
    11.  
    12.  
    13.             // The size changed. Enable the CSF component
    14.             // This is not needed here in the current case (replace it with vh.contentSizeFitter.enabled=true if you want),
    15.             // since we're using the "ForceXXX" version of the layout rebuilding function,
    16.             // but we should do it in general, in case your viewholder has some own logic to be executed right before a rebuild event.
    17.             vh.MarkForRebuild();
    18.  
    19.             // The CSF component will resize the root accordingly
    20.             // Use Canvas.ForceUpdateCanvases() instead, if on old unity version
    21.             LayoutRebuilder.ForceRebuildLayoutImmediate(vh.root);
    22.  
    23.             // The CSF component was used to estimate the item's size, but the adapter itself
    24.             // should set it (along with correctly setting the item's position, shifting other items, updating sizes cache etc.)
    25.             RequestChangeItemSizeAndUpdateLayout(vh, vh.root.rect.height);
    26.  
    27.             // MarkForRebuild has set it to true; We used it, now set it back to false - not too important,
    28.             // because it'll be disabled anyway next time it's recycled, but it's nice to clean after ourselves:)
    29.             vh.contentSizeFitter.enabled = false;
    30.         }
    Created method in MyViewsHolder class:
    Code (CSharp):
    1.         public void UpdateExpandedState(bool expanded)
    2.         { titleText.gameObject.SetActive(expanded); }
    Removed the model and click event from the ViewsHolder class (see note below) and added this code at the bottom of UpdateFromModel():
    Code (CSharp):
    1.             //titleText.gameObject.SetActive(model.expanded);
    2.             if (titleText.gameObject.activeSelf != model.expanded)
    3.             {
    4.                 UpdateExpandedState(model.expanded);
    5.                 model.HasPendingSizeChange = true;
    6.             }


    Note: you shouldn't place the model inside the ViewsHolder anyway - this one is being recycled and you may run into some seemengly unexplainable issues if you rely too much on that model stored in the VH's field. The model is already stored in _Params.Data (or wherever you choose to store it, in case you don't use a Params class which also stores the data for you).

    Hope this helps
     
    mulova and justtime like this.
  33. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    424
    It works like a charm! Thanks!
    One moment btw, is it possible to combine two methods : expand text, but making it smoothly like in EpandCollapseOnClick ?
     
    Last edited: Jun 10, 2018
  34. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Yes, but it involves combining this with the present expanding functionality to fixed size (you can take it from SimpleTutorial.cs). On click, you can use the CSF to just grab the real size, then setting it back (so no need to also notify the adapter at this point) and then trigger the EpandCollapseOnClick's functionality (after setting the target size for the animation manually, because the original implementation just makes it expand to <original size * a constant factor set in inspector>), but you'd need to make sure you're handling quite a lot of edge cases - at least those handled in the other example scripts that use EpandCollapseOnClick.

    There are surely more ways of doing this, but this is what came into my mind now
     
  35. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    [!IMPORTANT] We'd like everyone still watching this thread (and newer posters) to answer the pool question, as it'll help both of us regarding the next version (v4) :D

    Thanks,
    Lucian
     
  36. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Hi, I am noticing some buggy behavior specifically when using the Snapper8 in conjunction with a loop items scroll view. Here is a video demoing the issue:
    Sometimes the snapping does not occur, and other times, the looping fails. I will note that this only appears to happen on mobile devices, but not from the Unity editor. Thanks for your time
     
  37. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey,
    I remember making the looping to also work when N = the minimum amount of items to be displayed (2, in this case) was very time-consuming and not worth it, especially because in v4.0 we'll have a totally different system.
    Having <minimum>+1 items should make it work, case in which you'd need to manually disable looping for N < 3.
    The snapper was just confused because we don't duplicate the items, but in theory it'd need 3 items (left, middle, right), and in this case it's just randomly picking one, which of course leads to this unstable behavior.

    Let me know if enabling looping only on N >= 3 solves it.

    But if you definitely need the looping even for 2 items: duplicate the first model and put it at the end of the list, so it'll go list=[model1, model2, model1]. For 1 item, duplicate it twice, so N will never go below 3.
    I find this an acceptable workaround.
    It'll be included in the next version's examples. So thanks for your time too, because I wouldn't have this idea otherwise :D
     
  38. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Thanks, I ended up basically doing [model1, model2, model1, model2]. I couldn't quite see how to do just [model1, model2, model1] without seeing model1 twice in a row.
     
  39. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    You're right. That's better
     
  40. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Version 4.0 (major changeset) will be released in ~2 weeks at 60$.
    Current users will be able to update, of course - an upgrade guide will be included. Don't forget to make a backup before!

    The plugin's core was hugely improved:
    - there's no more need for a ScrollRect. We've created our own, almost identical in functionality (elastic movement, inertia etc), but improved and more accessible.
    - the performance increased drastically. We confirmed 2Billion(max integer value) items to work on low end devices at 60fps. That's a 2000x increase from v3.0.
    - the API is more consistent and rich, but compatible with the previous version, of course.
    - several new features were added (ex. parallax background scroll; variable number of columns/rows in a grid, depending on the screen size) as well as new scenes (ex. nested scrollviews).

    Stay tuned! :)
     
    Last edited: Jul 8, 2018
    Airship and stevenatunity like this.
  41. skyrusfxg

    skyrusfxg

    Joined:
    Jan 14, 2016
    Posts:
    127
    Hello. There is an Action - ItemsRefreshed but when it called VisibleItems is still not created (VisibleItemsCount = 0). In few frames VisibleItems will be created. Are the any callback after items were refreshed and all VisibleItems where instantiated and added to VisibleItems List ?
     
  42. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey

    ItemsRefreshed is intended to be called initially, when there are 0 items in the list and thus 0 viewholders generated.
    You can see this convention in many other frameworks/libraries, because it's helpful for you in case you need to initialize some things before you actually set up the count. Concrete example: you have a Text component which reflects the number of items. You set its text to 999 at edit-time to visualize it, but when you enter play mode you want it to immediately show 0 while you load your models, potentially from a remote source, so that the 999 text will be naturally replaced with 0 during download. After the items download, the text will be set to the number of items.

    If your code breaks when you have 0 items, you should fix that instead (generally).

    If you want the event to be called after init, simply subscribe to it after base.Start() is being called, in Start().

    Let me know if this solved it
     
  43. skyrusfxg

    skyrusfxg

    Joined:
    Jan 14, 2016
    Posts:
    127
    Simple example. I refreshed scroll by levels plate.
    upload_2018-6-24_10-39-41.png
    And after i have been refreshed them and levels plates all are ready i want to start animation for each visible item. I did it that way:
    upload_2018-6-24_10-43-22.png
    Are there other proper ways to wait all visible items will be refreshed?
     

    Attached Files:

  44. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Note that visibleitemscount means the number of viewsholders that are currently seen deprnding on the viewport's size, and Not the total number of items (you have that data accessible from your side, as _Params.Data.Count).
    As for waiting until all vhs are created, do you mean my previous solution is not clear or did you try it and it didn't work?
     
  45. nola_dev

    nola_dev

    Joined:
    Oct 18, 2015
    Posts:
    3
    Hi, I saw a newly released video for SRIA Version 4.0 on YouTube.
    When will we be able to get the update from the Asset Store? It has some new features I would like to start using in my project.
     
  46. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey,
    It usually takes a week for a major update.
    I'll post here as well :)

    Lucian
     
  47. junestone

    junestone

    Joined:
    May 30, 2017
    Posts:
    42
    The screen flickers a lot when scrolling in the Sample Scene.
    Unity 2017.4p6f1, with Metal on mac.
     
  48. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hm, we never experienced this. The screen or the ScrollRect only? If it's the screen, I'm sure there's a very low chance for it to be caused by SRIA.

    If it's the ScrollRect only, here's how should we start to find the root cause:

    I need to know what behavior do you get in the following situations:
    - patch Unity version on Windows
    - non-patch Unity version on Windows
    - non-patch Unity version on Mac, without metal
    - patch Unity version on Mac, withhout metal

    Can you also confirm if you get this by using a normal ScrollRect with 80-150 items or exclusively when using SRIA?

    SRIA 4.0 should be live in about 1 week. This version removes the need for a ScrollRect and has its core rewritten for performance, consistency & more control over the input events. Although IDK if it'll solve this problem, as it seems a unity-related one.

    Let me know
    Lucian
     
  49. junestone

    junestone

    Joined:
    May 30, 2017
    Posts:
    42
    Im sorry that I can't install such Unity versions on my computer right now for some kinda reasons.
    But I tested OpenGL it works fine.
    I'm using Unity 2017.4.6f1 LTS on Mac.
    Also can't test on Windows right now because my computer is mac only at the moment.
    Maybe later I can do more test.
    Summary: Metal not ok on that version of Unity, OpenGL works well.
     
  50. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Help me understand. Which of the following is the case for Unity 2017.4.6f1 LTS on Mac with Metal?:
    a) Unity is not usable
    b) Unity's makes the entire screen flicker
    c) Unity's ScrollRect alone flickers
    d) Unity's ScrollRect flickers only if you attach SRIA to it

    Thanks