列表视图和树视图是__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary 设计中常见的功能。您可以使用 UI 工具包在自定义编辑器窗口或运行时中创建列表和树视图。此示例演示如何在自定义编辑器窗口中创建列表和树视图。您可以使用 UXML 配置列表和树的结构,然后在 C# 脚本中动态填充。
此示例创建了四个编辑器窗口,其中显示以下内容:
可以在此 GitHub 代码仓库中找到此示例创建的完整文件。
本指南适用于熟悉 Unity 编辑器、UI 工具包和 C# 脚本的开发者。在开始之前,请熟悉以下内容:
在由两组行星和树视图根节点组成的 C# 脚本中创建数据。
使用任何模板在 Unity 中创建项目。
在项目窗口中,创建一个名为 Editor 的文件夹。
在 Editor 文件夹中,创建一个名为 PlanetsWindow.cs 的 C# 脚本。
将 PlanetsWindow.cs 的内容替换为以下内容:
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
// Base class for all windows that display planet information.
public class PlanetsWindow : EditorWindow
{
[SerializeField]
protected VisualTreeAsset uxmlAsset;
// Nested interface that can be either a single planet or a group of planets.
protected interface IPlanetOrGroup
{
public string name
{
get;
}
public bool populated
{
get;
}
}
// Nested class that represents a planet.
protected class Planet : IPlanetOrGroup
{
public string name
{
get;
}
public bool populated
{
get;
}
public Planet(string name, bool populated = false)
{
this.name = name;
this.populated = populated;
}
}
// Nested class that represents a group of planets.
protected class PlanetGroup : IPlanetOrGroup
{
public string name
{
get;
}
public bool populated
{
get
{
var anyPlanetPopulated = false;
foreach (Planet planet in planets)
{
anyPlanetPopulated = anyPlanetPopulated || planet.populated;
}
return anyPlanetPopulated;
}
}
public readonly IReadOnlyList<Planet> planets;
public PlanetGroup(string name, IReadOnlyList<Planet> planets)
{
this.name = name;
this.planets = planets;
}
}
// Data about planets in our solar system.
protected static readonly List<PlanetGroup> planetGroups = new List<PlanetGroup>
{
new PlanetGroup("Inner Planets", new List<Planet>
{
new Planet("Mercury"),
new Planet("Venus"),
new Planet("Earth", true),
new Planet("Mars")
}),
new PlanetGroup("Outer Planets", new List<Planet>
{
new Planet("Jupiter"),
new Planet("Saturn"),
new Planet("Uranus"),
new Planet("Neptune")
})
};
// Expresses planet data as a list of the planets themselves. Needed for ListView and MultiColumnListView.
protected static List<Planet> planets
{
get
{
var retVal = new List<Planet>(8);
foreach (var group in planetGroups)
{
retVal.AddRange(group.planets);
}
return retVal;
}
}
// Expresses planet data as a list of TreeViewItemData objects. Needed for TreeView and MultiColumnTreeView.
protected static IList<TreeViewItemData<IPlanetOrGroup>> treeRoots
{
get
{
int id = 0;
var roots = new List<TreeViewItemData<IPlanetOrGroup>>(planetGroups.Count);
foreach (var group in planetGroups)
{
var planetsInGroup = new List<TreeViewItemData<IPlanetOrGroup>>(group.planets.Count);
foreach (var planet in group.planets)
{
planetsInGroup.Add(new TreeViewItemData<IPlanetOrGroup>(id++, planet));
}
roots.Add(new TreeViewItemData<IPlanetOrGroup>(id++, group, planetsInGroup));
}
return roots;
}
}
}
要创建列表视图,请首先使用 UI Builder 创建 ListView UI 控件。然后,使用 ListView 创建一个自定义编辑器窗口,并在 C# 脚本中定义获取列表数据的位置。最后,将 UXML 文件引用到 C# 脚本。
右键单击 Editor 文件夹。
选择创建 (Create) > UI 工具包 (UI Toolkit) > 编辑器窗口 (Editor Window)。
在 C# 框中,输入 PlanetsListView 并清除 USS 复选框。这会创建两个文件:PlanetsListView.uxml 和 PlanetsListView.cs。
双击 PlanetsListView.uxml 可在 UI Builder 中将其打开。
在层级视图 (Hierarchy) 窗口中,删除标签 (Label) 控件并添加 ListView 控件。
在层级视图 (Hierarchy) 窗口中选择 ListView 控件。
在检视面板 (Inspector) 窗口中,将固定项高 (Fixed Item Height) 设置为 20。
保存更改。PlanetsListView.uxml 应如下所示:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<ui:ListView fixed-item-height="20" />
</ui:UXML>
将 PlanetsListView.cs 的内容替换为以下内容:
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsListView : PlanetsWindow
{
[MenuItem("Planets/Standard List")]
static void Summon()
{
GetWindow<PlanetsListView>("Standard Planet List");
}
void CreateGUI()
{
// The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent
// class PlanetsWindow.
uxmlAsset.CloneTree(rootVisualElement);
var listView = rootVisualElement.Q<ListView>();
// Set ListView.itemsSource to populate the data in the list.
listView.itemsSource = planets;
// Set ListView.makeItem to initialize each entry in the list.
listView.makeItem = () => new Label();
// Set ListView.bindItem to bind an initialized entry to a data item.
listView.bindItem = (VisualElement element, int index) =>
(element as Label).text = planets[index].name;
}
}
在 Unity 中,在项目 (Project) 窗口中选择 PlanetsListView.cs,然后将 PlanetsListView.uxml 拖入检视面板 (Inspector) 中的 Uxml 字段。
从菜单中选择行星 (Planets) > 标准列表 (Standard List) 以查看行星列表。
要创建具有多个列的列表视图,请首先创建一个 MultiColumnListView UI 控件,并在 UXML 文件中定义列数和列标题。然后,使用 MultiColumnListView 创建一个自定义编辑器窗口,并在 C# 脚本中定义每列中列表的数据获取位置。最后,将 UXML 文件引用到 C# 脚本。
右键单击 Editor 文件夹。
选择创建 (Create) > UI 工具包 (UI Toolkit) > UI 文档 (UI Document) 以创建 UXML 文件,并将其命名为 PlanetsMultiColumnListView.uxml。
在文本编辑器中打开 PlanetsMultiColumnListView.uxml。
将 PlanetsMultiColumnListView.uxml 的内容替换为以下内容:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<ui:MultiColumnListView fixed-item-height="20">
<!-- Columns and Column aren't Visual Elements or controls. They are considered attributes of MultiColumnListView. -->
<ui:Columns>
<ui:Column name="name" title="Name" width="80" />
<ui:Column name="populated" title="Populated?" width="80" />
</ui:Columns>
</ui:MultiColumnListView>
</ui:UXML>
在 Editor 文件夹中,创建一个名为 PlanetsMultiColumnListView.cs 的 C# 文件。
将 PlanetsMultiColumnListView.cs 的内容替换为以下内容:
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsMultiColumnListView : PlanetsWindow
{
[MenuItem("Planets/Multicolumn List")]
static void Summon()
{
GetWindow<PlanetsMultiColumnListView>("Multicolumn Planet List");
}
void CreateGUI()
{
// The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent
// class PlanetsWindow.
uxmlAsset.CloneTree(rootVisualElement);
var listView = rootVisualElement.Q<MultiColumnListView>();
// Set MultiColumnListView.itemsSource to populate the data in the list.
listView.itemsSource = planets;
// For each column, set Column.makeCell to initialize each cell in the column.
// You can index the columns array with names or numerical indices.
listView.columns["name"].makeCell = () => new Label();
listView.columns["populated"].makeCell = () => new Toggle();
// For each column, set Column.bindCell to bind an initialized cell to a data item.
listView.columns["name"].bindCell = (VisualElement element, int index) =>
(element as Label).text = planets[index].name;
listView.columns["populated"].bindCell = (VisualElement element, int index) =>
(element as Toggle).value = planets[index].populated;
}
}
在 Unity 的项目 (Project) 窗口中选择 PlanetsMultiColumnListView.cs。
将 PlanetsMultiColumnListView.uxml 拖入检视面板 (Inspector) 中的 Uxml 字段。
从菜单中选择行星 (Planets) > 多列列表 (Multicolumn List) 以查看两列列表。一列包含行星列表。另一列具有指示是否填充行星的开关。
要在自定义编辑器中创建树视图,请先在 UXML 文件中创建 TreeView UI 控件。然后,使用 TreeView 创建一个自定义编辑器窗口,并通过 C# 脚本定义树节点的数据获取位置。最后,将 UXML 文件引用到 C# 脚本。
在 Editor 文件夹中,创建一个名为 PlanetsTreeView.uxml 的 UXML 文件。
将 PlanetsTreeView.uxml 的内容替换为以下内容:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<ui:TreeView fixed-item-height="20" />
</ui:UXML>
在 Editor 文件夹中,创建一个名为 PlanetsTreeView.cs 的 C# 文件。
将 PlanetsTreeView.cs 的内容替换为以下内容:
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsTreeView : PlanetsWindow
{
[MenuItem("Planets/Standard Tree")]
static void Summon()
{
GetWindow<PlanetsTreeView>("Standard Planet Tree");
}
void CreateGUI()
{
// The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent
// class PlanetsWindow.
uxmlAsset.CloneTree(rootVisualElement);
var treeView = rootVisualElement.Q<TreeView>();
// Call TreeView.SetRootItems() to populate the data in the tree.
treeView.SetRootItems(treeRoots);
// Set TreeView.makeItem to initialize each node in the tree.
treeView.makeItem = () => new Label();
// Set TreeView.bindItem to bind an initialized node to a data item.
treeView.bindItem = (VisualElement element, int index) =>
(element as Label).text = treeView.GetItemDataForIndex<IPlanetOrGroup>(index).name;
}
}
在 Unity 的项目 (Project) 窗口中选择 PlanetsTreeView.cs。
将 PlanetsTreeView.uxml 拖入检视面板 (Inspector) 中的 Uxml 字段。
从菜单中选择行星 (Planets) > 标准树 (Standard Tree) 以查看按节点分组的两个行星列表。每个节点旁边都有一个箭头。如果选择箭头,该窗口将显示组中的行星。
要在自定义编辑器中创建具有多个列的树视图,请首先创建 MultiColumnTreeView UI 控件并在 UXML 文件中定义列。然后,使用 MultiColumnTreeView 创建一个自定义编辑器窗口,并在 C# 脚本中定义每列的数据获取位置。最后,将 UXML 文件引用到 C# 脚本。
在 Editor 文件夹中,创建一个名为 PlanetsMultiColumnTreeView.uxml 的 UXML 文件。
将 PlanetsMultiColumnTreeView.uxml 的内容替换为以下内容:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<ui:MultiColumnTreeView fixed-item-height="20">
<!-- Columns and Column aren't Visual Elements or controls; they are considered attributes of MultiColumnListView. -->
<ui:Columns>
<ui:Column name="name" title="Name" width="120" />
<ui:Column name="populated" title="Populated?" width="80" />
</ui:Columns>
</ui:MultiColumnTreeView>
</ui:UXML>
在 Editor 文件夹中,创建一个名为 PlanetsMultiColumnTreeView.cs 的 C# 文件。
将 PlanetsMultiColumnTreeView.cs 的内容替换为以下内容:
using UnityEditor;
using UnityEngine.UIElements;
public class PlanetsMultiColumnTreeView : PlanetsWindow
{
[MenuItem("Planets/Multicolumn Tree")]
static void Summon()
{
GetWindow<PlanetsMultiColumnTreeView>("Multicolumn Planet Tree");
}
void CreateGUI()
{
// The protected variable 'uxmlAsset' is a VisualTreeAsset defined in the parent
// class PlanetsWindow.
uxmlAsset.CloneTree(rootVisualElement);
var treeView = rootVisualElement.Q<MultiColumnTreeView>();
// Call MultiColumnTreeView.SetRootItems() to populate the data in the tree.
treeView.SetRootItems(treeRoots);
// For each column, set Column.makeCell to initialize each node in the tree.
// You can index the columns array with names or numerical indices.
treeView.columns["name"].makeCell = () => new Label();
treeView.columns["populated"].makeCell = () => new Toggle();
// For each column, set Column.bindCell to bind an initialized node to a data item.
treeView.columns["name"].bindCell = (VisualElement element, int index) =>
(element as Label).text = treeView.GetItemDataForIndex<IPlanetOrGroup>(index).name;
treeView.columns["populated"].bindCell = (VisualElement element, int index) =>
(element as Toggle).value = treeView.GetItemDataForIndex<IPlanetOrGroup>(index).populated;
}
}
在 Unity 的项目 (Project) 窗口中选择 PlanetsMultiColumnTreeView.cs。
将 PlanetsMultiColumnTreeView.uxml 拖入检视面板 (Inspector) 中的 Uxml 字段。
选择行星 (Planets) > 多列树 (Multicolumn Tree) 可以查看具有两列的列表。第一列包含两个按节点分组的行星列表。每个节点旁边都有一个箭头。如果选择箭头,该窗口将显示该组中的行星和开关列表。