Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Custom ListView

Discussion in 'UI Toolkit' started by imaewyn, Mar 20, 2020.

  1. imaewyn

    imaewyn

    Joined:
    Apr 23, 2016
    Posts:
    211
    So, im drop idea of Loop creation list of elements, its so hard for catching and edit. Now im try implement it on ListView.


    This my code for generate simple ListView with VisualElement

    Code (CSharp):
    1. public void OnEnable()
    2.     {
    3.         int itemCount = 100;
    4.         var items = new List<VisualElement>(itemCount);
    5.         for (int i = 0; i < itemCount; i++)
    6.         {
    7.             items.Add(MakeItem());
    8.         }
    9.  
    10.         Func<VisualElement> makeItem = () => new VisualElement();
    11.         VisualElement MakeItem()
    12.         {
    13.             var Fields = new VisualElement();
    14.             var lbl = new Label();
    15.             var textfield = new TextField();
    16.             textfield.label = "Test text field";
    17.             Fields.Add(lbl);
    18.             Fields.Add(textfield);
    19.             lbl.text = "Test label";                    
    20.             return Fields;
    21.         }
    22.  
    23.         Action<VisualElement, int> bindItem = (e, i) => e.Add(items[i]);
    24.         const int itemHeight = 40;
    25.  
    26.         var listView = new ListView(items, itemHeight, makeItem, bindItem);
    27.  
    28.         listView.selectionType = SelectionType.Multiple;
    29.  
    30.         listView.onItemChosen += obj => Debug.Log(obj);
    31.         listView.onSelectionChanged += objects => Debug.Log(objects);
    32.  
    33.         listView.style.flexGrow = 1.0f;
    34.  
    35.         rootVisualElement.Add(listView);
    36.        
    37.     }
    In each scroll elements overlays like this
    ListView.gif

    I think this happens at the moment of adding a new item (e.Add()) and the old items are attached to each other in the same way without freeing the past. But I have not yet come up with another way to implement this thing.
    I know that I ask too often, but help me pls
     
  2. imaewyn

    imaewyn

    Joined:
    Apr 23, 2016
    Posts:
    211
    Ok, I am ready to admit it, im dumb. If im change makeItem from new VisualElement() to my item (MakeItem()) and change e.add() on e = items, all works


    Code (CSharp):
    1. public void OnEnable()
    2.     {
    3.         int itemCount = 100;
    4.         var items = new List<VisualElement>(itemCount);
    5.         for (int i = 0; i < itemCount; i++)
    6.         {
    7.             items.Add(MakeItem());
    8.         }
    9.  
    10.         Func<VisualElement> makeItem = () => MakeItem();
    11.         VisualElement MakeItem()
    12.         {
    13.             var Fields = new VisualElement();
    14.             var lbl = new Label();
    15.             var textfield = new TextField();
    16.             textfield.label = "Test text field";
    17.             Fields.Add(lbl);
    18.             Fields.Add(textfield);
    19.             lbl.text = "Test label";                    
    20.             return Fields;
    21.         }
    22.  
    23.         Action<VisualElement, int> bindItem = (e, i) => e = items[i];
    24.         const int itemHeight = 40;
    25.  
    26.         var listView = new ListView(items, itemHeight, makeItem, bindItem);
    27.  
    28.         listView.selectionType = SelectionType.Multiple;
    29.  
    30.         listView.onItemChosen += obj => Debug.Log(obj);
    31.         listView.onSelectionChanged += objects => Debug.Log(objects);
    32.  
    33.         listView.style.flexGrow = 1.0f;
    34.  
    35.         rootVisualElement.Add(listView);
    36.        
    37.     }
     
  3. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    396
    The ListView paradigm is to create VisualElements only for items that are displayed on the screen. Usually, the items[] array is your dataSource. Could be strings, integers or more complex objects, not VisualElements.

    The makeItem delegate is called when the ListView needs a VisualElement hiearchy to display an item.
    the BindItem is made to change what's displayed on the visualElement hierarchy created before.

    Since the ListView pools and reuse elements are they are scrolled out of the view, makeItem will be called way less often than BindItem, thus always adding elements during bind, without remove what was there is not the way to go. Usually, you don't have to add or remove elements during bindItem, only change labels text and field values.
    If you need to hook ChangeEvent callbacks, you might want to unregister them in an unbindItem delegate

    Hope that helps
     
    imaewyn likes this.
  4. imaewyn

    imaewyn

    Joined:
    Apr 23, 2016
    Posts:
    211

    So yes, after more complex testing, I came to the conclusion that I can not represent and manage my data in this way, May be u canshow, how i can use list view for complex objects? Like list with string's and int's.


    I found examples of uielements, dont know how i can miss it. I think its contain all requied information
     
    Last edited: Mar 20, 2020
  5. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    If you go to Unity's main menu, under Window > UI > UIElements Samples and find List View, you'll see an example of how to create a ListView from a list of strings.
     
    owlrazum likes this.
  6. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    Is it possible to create a horizontal list view (items are arranged left-to-right instead of top-to-bottom)? I couldn't get one to work and the fact that item (row) height is required makes me wonder...
     
  7. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    No, ListView does not support horizontal layout. You'll need to revert to using a ScrollView if you need horizontal.
     
    lclemens likes this.
  8. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    Do ListView and ScrollView support touchscreen devices (scroll by flicking up/down/left/right)?
     
  9. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    Not yet.
     
    chriseborn likes this.
  10. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    Now that UI Toolkit supports the new input system, the only thing keeping me from switching is support for touchscreen with ListView and/or ScrollView. I couldn't figure out where that fits into the roadmap... is it something coming up in the next couple of months or is that something that's a long way off?
     
    distastee likes this.
  11. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    So...... Touch support for UI Toolkit ListView and ScrollView ...... Tomorrow, next month, this year, next year, never?
     
    devotionsolutions and distastee like this.
  12. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    808
  13. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
  14. stevphie123

    stevphie123

    Joined:
    Mar 24, 2021
    Posts:
    81
    If we somehow have an option to toggle off the internal pooling, this would be much easier...

    having to Register and Unregister callbacks via unbind will bloat our project like insanely.