UI Toolkit 中的容器,主要包含 VisualElement、ScrollView、ListView、GroupBox 等,官方介绍详见→UXML elements reference

VisualElement(空容器)

VisualElement 是一个空容器,便于组织和管理元素,官方介绍见→UXML element VisualElement

属性介绍

View Data Key:用于视图数据持久化(如:树展开状态、滚动位置、缩放级别),作为视图数据保存 / 加载的键,如果不设置此键将禁用该容器的持久性。

Picking Mode:判断是否可以在 mouseEvents 期间选择此容器。

Tooltip:鼠标悬停到该容器上时弹出的提示文字。

Usage Hints:预期使用模式,便于系统加速某些操作。

Tab Index:用于对焦点环中的焦点对象进行排序。

Focusable:容器是否能获得焦点。

说明:View Data Key、Picking Mode、Tooltip、Usage Hints、Tab Index、Focusable 都是基类属性,后文若出现这些属性将不再赘述。

获取根VisualElement容器

VisualElement rootVisualElement = GetComponent<UIDocument>().rootVisualElement;

注册事件回调(RegisterCallback)

public class RegisterCallbackDemo : MonoBehaviour
{
    private void Awake()
    {
      VisualElement visualElement =  GetComponent<UIDocument>().rootVisualElement;
        visualElement.RegisterCallback<MouseDownEvent>(OnClickDown);
        visualElement.RegisterCallback<ClickEvent>(OnClick);
    }

    private void OnClick(ClickEvent evt)
    {
        Debug.Log("target=" + evt.target);

    }

    private void OnClickDown(MouseDownEvent evt)
    {
        Debug.Log("mousePosition=" + evt.mousePosition + ", pressedButtons=" + evt.pressedButtons); // 1:左键, 2:右键, 4:中键
    }
}

效果:

说明:注册的事件主要有以下几种,官方介绍见→Event reference。

MouseDownEvent:鼠标按下时触发的事件。

MouseUpEvent:鼠标抬起时触发的事件。

ClickEvent:鼠标左键点击时触发的事件。

MouseOverEvent:鼠标进入元素时触发的事件。

MouseOutEvent:鼠标离开元素时触发的事件。

MouseMoveEvent:鼠标移动时触发的事件。

MouseEnterEvent:鼠标进入元素或其子元素时触发的事件。

MouseLeaveEvent:鼠标离开元素和其所有子元素时触发的事件。

MouseCaptureEvent:处理器开始捕获鼠标后触发的事件。

MouseCaptureOutEvent:处理器停止捕获鼠标后触发的事件。

MouseEnterWindowEvent:鼠标进入窗口时触发的事件。

MouseLeaveWindowEvent:鼠标离开窗口时触发的事件。

WheelEvent:鼠标滑轮滚动时触发的事件。

添加事件操作器(AddManipulator)

public class ManipulatorDemo : MonoBehaviour
{
    private VisualElement rootVisualElement;

    private void Awake()
    {
        // 获取UI文档的根视觉元素
        rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
        
        // 创建一个Clickable操纵器,指定回调函数
        Clickable leftClickManipulator = new Clickable(onCtrlDoubleClicked);
        
        // 清除默认的激活条件
        leftClickManipulator.activators.Clear();
        
        // 添加自定义的激活条件:Ctrl+双击左键
        leftClickManipulator.activators.Add(new ManipulatorActivationFilter()
        {
            button = MouseButton.LeftMouse, // 鼠标左键
            clickCount = 2,                 // 双击
            modifiers = EventModifiers.Control // 需要按住Ctrl键
        });
        
        // 将操纵器添加到根视觉元素
        rootVisualElement.AddManipulator(leftClickManipulator);
    }

    // 事件处理函数
    private void onCtrlDoubleClicked(EventBase @base)
    {
        print("onCtrlDoubleClicked");
    }
}
  1. Manipulator(操纵器)

    • UI Toolkit 中处理输入事件的高级抽象

    • 封装了事件处理逻辑,使代码更简洁

  2. Clickable

    • 专门处理点击事件的操纵器

    • 支持配置多种点击条件(单击、双击、长按等)

  3. ManipulatorActivationFilter

    • 定义激活操纵器的条件

    • 可以组合多种条件(按键、点击次数、修饰键等)

  4. EventModifiers

    • 表示键盘修饰键(Ctrl、Shift、Alt等)

    • 可以组合使用,如 EventModifiers.Control | EventModifiers.Shift

效果:

ScrollView(滚动容器)

属性介绍

Mode:控制用户滚动内容的方式,取值有 Vertical(垂直滚动)、Horizontal(水平滚动)、Vertical And Horizontal(垂直和水平滚动)。

Nested Interaction Kind:滑动到边界后的行为,取值有 default(反弹)、Stop Scrolling(停止滑动)、Forward Scrolling(继续向前滑动)。

Horizontal Scroller Visibility:水平滚动条的可见性,取值有 Auto(仅在内容显示不下时才显示滑动条)、Always Visible(一直可见)、Hidden(一直隐藏)。

Vertical Scroller Visibility:垂直滚动条的可见性,取值有 Auto(仅在内容显示不下时才显示滑动条)、Always Visible(一直可见)、Hidden(一直隐藏)。

Horizontal Page Size:控制水平滑动的速度。

Vertical Page Size:控制垂直滑动的速度。

Touch Scroll Type:触摸滑动类型,Unrestricted(不受约束的)、Elastic(弹性的)、Clamped(夹紧的)。

Scroll Deceleration Rate:滑动停止时的减速度(速度的导数,为 0 时立刻停止滑动)。

Elasticity:滑动到边界时的弹性值。

添加元素

将元素拖拽到 ScrollView 上,会自动放在其 unity-content-container 元素下面,如下。

也可以通过以下代码添加元素。

VisualElement rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
ScrollView scrollview = rootVisualElement.Q<ScrollView>();
scrollview.Add(new Label("LabelContent"));

ListView(列表)

ListView 是一个列表容器,官方介绍见→UXML element ListView

属性介绍

BindingPath:目标属性绑定的路径。

Fixed Item Height:列表中 item 的高度,以像素为单位。

Virtualization Method:设置 item 高度是固定的还是动态的,取值有 Fixed Height(固定高度)、Dynamic Height(动态高度)。

Show Border:是否显示边框。

Selection Type:选择类型,取值有 None(禁止选中)、Single(只能选中单个 item)、Multiple(可以选中多个 item)。

Show Alternation Row Backgrounds:显示交替行背景,取值有 None(不显示交替行背景)、Content Only(有内容时才显示交替行背景)、All(一直显示交替行背景)。

Show Foldout Header:是否显示折叠页眉。

Header Title:页眉标题。

Show Add Remove Footer:是否显示添加 / 删除页脚,如果显示,在页脚会出现 "+" 和 "-" 按钮。

Reorderable:是否允许 item 重排序。

Reorder Mode:重排序模式,取值有 Simple(在重排序时显示标准的蓝线拖动器)、Animated(在每个 item 之前添加拖拽句柄,可以用来拖拽单个 item)。

Show Bound Collection Size:是否显示 item 数。

Horizontal Scrolling:是否可以水平滑动。

ListView的使用

public class ListViewDemo : MonoBehaviour
{
    private VisualElement root; //根容器
    private ListView listView; //列表
    private string[] itemsTitle = new string[] {"First","Second","Third","Fourth"};//item的标题
    private int[] itemsData = new int[] { 0, 1, 2, 3 };//item的数值

    [System.Obsolete]
    private void Awake()
    {
        root = GetComponent<UIDocument>().rootVisualElement;
        listView = root.Q<ListView>();
        listView.fixedItemHeight = 60;
        listView.itemsSource = itemsData;
        listView.makeItem += MakeItem;
        listView.bindItem += BindItem;
        listView.selectionChanged += SelectionChanged;
    }

    private void SelectionChanged(IEnumerable<object> enumerable)//选中事件
    {
        foreach (object item in enumerable)
        {
            int data = (int)item;
            print(data);
        }
    }

    private void BindItem(VisualElement element, int arg2) //绑定item
    {
        Label label = element as Label;
        label.text = itemsTitle[arg2];
    }

    private VisualElement MakeItem()   //创建item元素,这里以label元素呈现
    {
        Label label = new Label();
        label.style.fontSize = 50;
        label.style.unityTextAlign = TextAnchor.MiddleCenter;
        return label;
    }
} 

运行后,点击 Second,显示如上。

结果

GroupBox(分组盒子)

GroupBox 是一个逻辑分组容器,官方介绍见→UXML element GroupBox

属性介绍

  • Text: 分组标题。Text: 分组标题。

GroupBox的使用

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;

public class GroupBoxDemo : MonoBehaviour
{
    private VisualElement root; //根容器
    private GroupBox groupBox; //分组盒子
    private string[] choiceLabel = new string[] { "First", "Second", "Third", "Fourth" };//标签

    private void Awake()
    {
        root = GetComponent<UIDocument>().rootVisualElement;
        groupBox = root.Q<GroupBox>();
        groupBox.text = "GroupBoxDemo";
        groupBox.style.fontSize = 50;
        root.Add(groupBox);
        for (int i = 0; i < choiceLabel.Length; i++)
        {
            addChoice(i);
        }
    }

    private void addChoice(int i) //添加单选项
    {
        RadioButton choice = new RadioButton();
        choice.text = choiceLabel[i];
        choice.style.fontSize = 50;
        VisualElement ve = choice.Query<VisualElement>().AtIndex(2);
        ve.style.marginRight = 10;
        choice.RegisterValueChangedCallback(e => OnDropdownValueChanged(i, e));
        groupBox.Add(choice);
    }

    private void OnDropdownValueChanged(int index,ChangeEvent<bool> e) //选项变化回调函数
    {
        Debug.Log("index=" + index + ", previousValue=" + e.previousValue + ", newValue=" + e.newValue);

    }
}

效果

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐