Version: 2022.1
언어: 한국어
리스트 및 트리 뷰 생성
리스트 뷰 런타임 UI 생성

복합 리스트 뷰 생성

이 예시에서는 복합 ListView를 생성하는 방법을 보여줍니다.

복잡한 데이터로 ListView를 생성하고 ListView를 시각적 요소에 바인딩하려면 다음을 수행합니다.

  • makeItembindItem을 사용하여 ListView를 데이터에 바인딩하고 적절한 콜백을 등록하며 필요에 따라 연결된 데이터 소스를 수정합니다.
  • unbindItem을 사용하여 ListView의 요소를 재활용하고 데이터의 바인딩을 해제합니다.
  • destroyItem을 사용하여 등록된 콜백을 지웁니다.

개요 예시

예시에서는 캐릭터 리스트를 사용하여 커스텀 에디터 창을 생성합니다.각 캐릭터에는 슬라이더와 컬러 팔레트가 있습니다.슬라이더를 움직이면 팔레트의 컬러가 변경됩니다.

슬라이더가 이동된 리스트의 일부 항목은 팔레트의 컬러가 다릅니다.
슬라이더가 이동된 리스트의 일부 항목은 팔레트의 컬러가 다릅니다.

이 예시에서 생성한 완성된 파일은 GitHub 저장소에서 확인할 수 있습니다.

선행 조건

이 가이드는 Unity 에디터, UI 툴킷, C# 스크립팅에 익숙한 개발자용입니다.시작하기 전에 먼저 다음을 숙지하십시오.

예시 생성

이 예시에서는 C# 스크립트에서 목록의 시각적 요소를 빌드합니다.VisualElement를 상속하는 커스텀 CharacterInfoVisualElement 클래스를 사용하고 커스텀 요소를 CharacterInfo 오브젝트에 바인딩합니다.

  1. 임의의 템플릿을 사용하여 Unity 프로젝트를 생성합니다.

  2. 프로젝트(Project) 창에서 Editor라는 폴더를 만듭니다.

  3. Editor 폴더에 다음 콘텐츠가 있는 ListViewExample.cs라는 C# 스크립트 파일을 생성합니다.

    using System;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;
    using UnityEngine.UIElements;
    
    public class ListViewExample :EditorWindow
    {
        // Gradient used for the HP color indicator.
        private Gradient hpGradient;
        private GradientColorKey[] hpColorKey;
        private GradientAlphaKey[] hpAlphaKey;
        
        // ListView is kept for easy reference.
        private ListView listView;
        
        // List of CharacterInfo items, bound to the ListView.
        private List<CharacterInfo> items;
        [MenuItem("Window/ListView Custom Item")]   
        public static void OpenWindow()
        {
            GetWindow<ListViewExample>().Show();
        }
        
        private void OnEnable()
        {
            SetGradient();
            
            // Create and populate the list of CharacterInfo objects.
            const int itemCount = 50;
            items = new List<CharacterInfo>(itemCount);
            for(int i = 1; i <= itemCount; i++)
            {
                CharacterInfo character = new CharacterInfo {name = $"Character {i}", maxHp = 100};
                character.currentHp = character.maxHp;
                items.Add(character);
            }
            
            // The ListView calls this to add visible items to the scroller.
            Func<VisualElement> makeItem = () =>
            {
                var characterInfoVisualElement = new CharacterInfoVisualElement();
                var slider = characterInfoVisualElement.Q<SliderInt>(name:"hp");
                slider.RegisterValueChangedCallback(evt =>
                {
                    var hpColor = characterInfoVisualElement.Q<VisualElement>("hpColor");
                    var i = (int)slider.userData;
                    var characterInfo = items[i];
                    characterInfo.currentHp = evt.newValue;
                    SetHp(slider, hpColor, characterInfo);
                });
                return characterInfoVisualElement;
            };
            
            // The ListView calls this if a new item becomes visible when the item first appears on the screen, 
            // when a user scrolls, or when the dimensions of the scroller are changed.
            Action<VisualElement, int> bindItem = (e, i) => BindItem(e as CharacterInfoVisualElement, i);
            
            // Height used by the ListView to determine the total height of items in the list.
            int itemHeight = 55;
            
            // Use the constructor with initial values to create the ListView.
            listView = new ListView(items, itemHeight, makeItem, bindItem);
            listView.reorderable = false;
            listView.style.flexGrow = 1f; // Fills the window, at least until the toggle below.
            listView.showBorder = true;
            rootVisualElement.Add(listView);
            
            // Add a toggle to switch the reorderable property of the ListView.
            var reorderToggle = new Toggle("Reorderable");
            reorderToggle.style.marginTop = 10f;
            reorderToggle.value = false;
            reorderToggle.RegisterValueChangedCallback(evt => listView.reorderable = evt.newValue);
            rootVisualElement.Add(reorderToggle);
        }
        
        // Sets up the gradient.
        private void SetGradient()
        {
            hpGradient = new Gradient();
            
            // HP at 0%:Red.At 10%:Dark orange.At 40%:Yellow.At 100%:Green.
            hpColorKey = new GradientColorKey[4];
            hpColorKey[0] = new GradientColorKey(Color.red, 0f);
            hpColorKey[1] = new GradientColorKey(new Color(1f, 0.55f, 0f), 0.1f); // Dark orange
            hpColorKey[2] = new GradientColorKey(Color.yellow, 0.4f);
            hpColorKey[3] = new GradientColorKey(Color.green, 1f);
            
            // Alpha is always full.
            hpAlphaKey = new GradientAlphaKey[2];
            hpAlphaKey[0] = new GradientAlphaKey(1f, 0f);
            hpAlphaKey[1] = new GradientAlphaKey(1f, 1f);
            hpGradient.SetKeys(hpColorKey, hpAlphaKey);
        }
        
        // Bind the data (characterInfo) to the display (elem).
        private void BindItem(CharacterInfoVisualElement elem, int i)
        {
            var label = elem.Q<Label>(name:"nameLabel");
            var slider = elem.Q<SliderInt>(name:"hp");
            var hpColor = elem.Q<VisualElement>("hpColor");
            slider.userData = i;
            CharacterInfo characterInfo = items[i];
            label.text = characterInfo.name;
            SetHp(slider, hpColor, characterInfo);
        }
        
        private void SetHp(SliderInt slider, VisualElement colorIndicator, CharacterInfo characterInfo)
        {
            slider.highValue = characterInfo.maxHp;
            slider.SetValueWithoutNotify(characterInfo.currentHp);
            float ratio = (float)characterInfo.currentHp / characterInfo.maxHp;
            colorIndicator.style.backgroundColor = hpGradient.Evaluate(ratio);
        }
        
        // This class inherits from VisualElement to display and modify data to and from a CharacterInfo.
        public class CharacterInfoVisualElement :VisualElement
        {
            // Use Constructor when the ListView uses makeItem and returns a VisualElement to be 
            // bound to a CharacterInfo data class.
            public CharacterInfoVisualElement()
            {
                var root = new VisualElement();
                
                // The code below to style the ListView is for demo purpose.It's better to use a USS file
                // to style a visual element.
                root.style.paddingTop = 3f;
                root.style.paddingRight = 0f;
                root.style.paddingBottom = 15f;
                root.style.paddingLeft = 3f;
                root.style.borderBottomColor = Color.gray;
                root.style.borderBottomWidth = 1f;
                var nameLabel = new Label() {name = "nameLabel"};
                nameLabel.style.fontSize = 14f;
                var hpContainer = new VisualElement();
                hpContainer.style.flexDirection = FlexDirection.Row;
                hpContainer.style.paddingLeft = 15f;
                hpContainer.style.paddingRight = 15f;
                hpContainer.Add(new Label("HP:"));
                var hpSlider = new SliderInt {name = "hp", lowValue = 0, highValue = 100};
                hpSlider.style.flexGrow = 1f;
                hpContainer.Add(hpSlider);
                var hpColor = new VisualElement();
                hpColor.name = "hpColor";
                hpColor.style.height = 15f;
                hpColor.style.width = 15f;
                hpColor.style.marginRight = 5f;
                hpColor.style.marginBottom = 5f;
                hpColor.style.marginLeft = 5f;
                hpColor.style.backgroundColor = Color.black;
                hpContainer.Add(hpColor);
                root.Add(nameLabel);
                root.Add(hpContainer);
                Add(root);
            }
        }
    
        // Basic data class used for a character, with a name and HP data.Use a list of CharacterInfo as
        // a data source for the ListView.The CharacterInfo can be bound to CharacterInfoVisualElement when needed.
        [Serializable]
        public class CharacterInfo
        {
            public string name;
            public int maxHp;
            public int currentHp;
        }
    }
    
  4. 예시를 확인하려면 메뉴에서 Window > ListView Custom Item을 선택합니다.

추가 리소스

리스트 및 트리 뷰 생성
리스트 뷰 런타임 UI 생성