Search Unity

Question Is there any step by step tutorial for ListView with custom templates

Discussion in 'UI Toolkit' started by jGate99, Jul 4, 2021.

  1. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    Hi there,

    Is there any Step by Step tutorial for ListView with custom template?

    Please advise
     
  2. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    jGate99 likes this.
  3. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
  4. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    i
    Item height is fixed to whatever you specified. I thin kit is for performance reasons.
     
    jGate99 likes this.
  5. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    i Meant listview will support "variable item height" eventually so each item takes height based on its content, and this is currently being worked on based on roadmap, so i want to know if that feature is availalble or not in most rcent beta builds
     
  6. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    Variable item height is supported since 2021.2. You can find more information here.
     
    jGate99 and Leslie-Young like this.
  7. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    Sorry for being a pain in the neck, but i dont see any example that showcase variable height in action
    example in the link is still using fixed height.

    Secondly, i'd like to create a variable item height where item will take height based on text in title and description

    [Title - Label]
    [Description - Label Multiline]
     
  8. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    Here's a simple example I created to get you started. You can create complex elements inside makeItem and they will take the content needed. The example is using Random.Range to simulate elements with different size.
    Code (CSharp):
    1. public class Item
    2. {
    3.     public readonly int index;
    4.  
    5.     public Item(int index)
    6.     {
    7.         this.index = index;
    8.     }
    9.  
    10.     public override string ToString()
    11.     {
    12.         return "index: " + index;
    13.     }
    14. }
    15.  
    16. public class ListViewExample : EditorWindow
    17. {
    18.     [MenuItem("Samples/ListViewExample")]
    19.     public static void ShowExample()
    20.     {
    21.         var wnd = GetWindow<ListViewExample>();
    22.         wnd.titleContent = new GUIContent("ListViewExample");
    23.     }
    24.  
    25.     public void CreateGUI()
    26.     {
    27.         const int itemCount = 1000;
    28.  
    29.         VisualElement root = this.rootVisualElement;
    30.  
    31.         var items = new List<Item>(itemCount);
    32.  
    33.         for (int i = 0; i < itemCount; i++)
    34.             items.Add(new Item(i));
    35.  
    36.         Func<VisualElement> makeItem = () =>
    37.         {
    38.             var box = new VisualElement();
    39.             box.Add(new Label());
    40.             box.style.height = Random.Range(20, 100);
    41.             return box;
    42.         };
    43.  
    44.         Action<VisualElement, int> bindItem = (e, i) =>
    45.         {
    46.             (e.ElementAt(0) as Label).text = items[i].index.ToString();
    47.         };
    48.      
    49.         var listView = new ListView();
    50.         listView.showAlternatingRowBackgrounds = AlternatingRowBackground.ContentOnly;
    51.         listView.virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight;
    52.         listView.itemsSource = items;
    53.         listView.makeItem = makeItem;
    54.         listView.bindItem = bindItem;
    55.      
    56.         root.Add(listView);
    57.     }
    58. }
     
    IndieForger and jGate99 like this.
  9. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945

    Thank you for the snippet, however it is giving items random size but not resizing items based on content
    Lets say we have this function which return random sizes of text

    Code (CSharp):
    1. public string GetRandomText(int size)
    2. {
    3.     StringBuilder builder = new StringBuilder();
    4.  
    5.     string legalCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    6.     char character;
    7.  
    8.     for (int i = 0; i < size; i++)
    9.     {
    10.         character = legalCharacters[random.Next(0, legalCharacters.Length)];
    11.         builder.Append(character);
    12.     }
    13.  
    14.     return builder.ToString();
    15. }
    And we set it to Label and now i want item to take height based on label content. How'd that be possible?
     
  10. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    By default elements take the size of their children so there's nothing special that need to be done to make ListView item take the size of the text.

    Here's the example updated with GetRandomText you created.
    Code (CSharp):
    1. public class Item
    2. {
    3.     public readonly int index;
    4.     public readonly string text;
    5.  
    6.     public Item(int index, string text)
    7.     {
    8.         this.index = index;
    9.         this.text = text;
    10.     }
    11. }
    12.  
    13. public class ListViewExample : EditorWindow
    14. {
    15.     [MenuItem("Samples/ListViewExample")]
    16.     public static void ShowExample()
    17.     {
    18.         var wnd = GetWindow<ListViewExample>();
    19.         wnd.titleContent = new GUIContent("ListViewExample");
    20.     }
    21.    
    22.     public void CreateGUI()
    23.     {
    24.         const int itemCount = 100;
    25.  
    26.         VisualElement root = this.rootVisualElement;
    27.  
    28.         var items = new List<Item>(itemCount);
    29.  
    30.         for (int i = 0; i < itemCount; i++)
    31.             items.Add(new Item(i, GetRandomText(Random.Range(20, 1000))));
    32.  
    33.         Func<VisualElement> makeItem = () =>
    34.         {
    35.             var box = new VisualElement();
    36.             var label = new Label();
    37.             label.style.fontSize = 14;
    38.             label.style.unityFontStyleAndWeight = FontStyle.Bold;
    39.             label.style.unityTextAlign = TextAnchor.MiddleCenter;
    40.             box.Add(label);
    41.             var text = new Label();
    42.             text.style.whiteSpace = WhiteSpace.Normal;
    43.             box.Add(text);
    44.             return box;
    45.         };
    46.  
    47.         Action<VisualElement, int> bindItem = (e, i) =>
    48.         {
    49.             (e.ElementAt(0) as Label).text = $"Item {items[i].index}\n\n";
    50.             (e.ElementAt(1) as Label).text = items[i].text;
    51.         };
    52.        
    53.         var listView = new ListView();
    54.         listView.showAlternatingRowBackgrounds = AlternatingRowBackground.ContentOnly;
    55.         listView.virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight;
    56.         listView.itemsSource = items;
    57.         listView.makeItem = makeItem;
    58.         listView.bindItem = bindItem;
    59.        
    60.         root.Add(listView);
    61.     }
    62.    
    63.     public string GetRandomText(int size)
    64.     {
    65.         StringBuilder builder = new StringBuilder();
    66.         string legalCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    67.         char character;
    68.         for (int i = 0; i < size; i++)
    69.         {
    70.             character = legalCharacters[Random.Range(0, legalCharacters.Length)];
    71.             builder.Append(character);
    72.         }
    73.         return builder.ToString();
    74.     }
    75. }
     
    Last edited: Jul 9, 2021
    IndieForger and jGate99 like this.
  11. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    You are AWESOME :D
     
    jonathanma_unity likes this.
  12. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    After few hours of trying to crack dynamic height from code, came back to the code and HERE it is...
    listView.showAlternatingRowBackgrounds = AlternatingRowBackground.ContentOnly;
    listView.virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight;


    MAGIC! Thank you very much!