UGUI——ToggleGroup

我的notion笔记

逻辑

直接继承自UIBehaviour

  1. 提供了RegisterToggle接口,Toggle组在SetToggleGroup中调用,将自身加入m_Toggles
public void RegisterToggle(Toggle toggle)
{
    if (!m_Toggles.Contains(toggle))
        m_Toggles.Add(toggle);

    if (!allowSwitchOff && !AnyTogglesOn())
    {
        toggle.isOn = true;
        NotifyToggleOn(toggle);
    }
}

  1. allowSwitchOff 用于控制再次点击是否关闭。如果是false的话,说明始终有一个是on状态,在toggle有变化时会进行检查
  2. UnregisterToggle接口,RegisterToggle的反向操作,也会有2的检查
public void UnregisterToggle(Toggle toggle)
{
    if (m_Toggles.Contains(toggle))
        m_Toggles.Remove(toggle);

    if (!allowSwitchOff && !AnyTogglesOn() && m_Toggles.Count != 0)
    {
        m_Toggles[0].isOn = true;
        NotifyToggleOn(m_Toggles[0]);
    }
}

  1. NotifyToggleOn接口,当toggle激活时调用。在toggle的isOn被设置时,会判断toggle是否有group,调用group的NotifyToggleOn接口。将除了指定的toggle外的toggle关闭。
/// <summary>
/// Notify the group that the given toggle is enabled.
/// </summary>
/// <param name="toggle">The toggle that got triggered on</param>
public void NotifyToggleOn(Toggle toggle, bool sendCallback = true)
{
    ValidateToggleIsInGroup(toggle);
    // disable all toggles in the group
    for (var i = 0; i < m_Toggles.Count; i++)
    {
        if (m_Toggles[i] == toggle)
            continue;

        if (sendCallback)
            m_Toggles[i].isOn = false;
        else
            m_Toggles[i].SetIsOnWithoutNotify(false);
    }
}

  1. Toggle的set,设置不一样的值时触发,如果有组的话,当设置为true或者组内没有toggle被激活且必须有一个toggle被激活时触发,调用组的NotifyToggleOn接口。 如果需要sendCallback时,调用public ToggleEvent onValueChanged = new ToggleEvent();接口触发回调。
void Set(bool value, bool sendCallback = true)
{
    if (m_IsOn == value)
        return;

    // if we are in a group and set to true, do group logic
    m_IsOn = value;
    if (m_Group != null && IsActive())
    {
        if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.allowSwitchOff))
        {
            m_IsOn = true;
            m_Group.NotifyToggleOn(this, sendCallback);
        }
    }

    // Always send event when toggle is clicked, even if value didn't change
    // due to already active toggle in a toggle group being clicked.
    // Controls like Dropdown rely on this.
    // It's up to the user to ignore a selection being set to the same value it already was, if desired.
    PlayEffect(toggleTransition == ToggleTransition.None);
    if (sendCallback)
    {
        UISystemProfilerApi.AddMarker("Toggle.value", this);
        onValueChanged.Invoke(m_IsOn);
    }
}

优化点

  1. List<Toggle> m_Toggles 申明为List,变长数组(类似C++的vector),而注册/反注册接口使用了Contain、Remove,除此之外还有些查找操作,更适合使用map/hashmap/set。
  2. AnyTogglesOn会在toggle初始化时和toggle设置值时被频繁调用,可以将结果缓存起来或在改变时动态记录,不用每次遍历。
  3. ActiveToggles 视项目调用频繁程度,可做2的优化

附录

C# List 源码Contains:

// Contains returns true if the specified element is in the List.
// It does a linear, O(n) search.  Equality is determined by calling
// item.Equals().
//
public bool Contains(T item) {
    if ((Object) item == null) {
        for(int i=0; i<_size; i++)
            if ((Object) _items[i] == null)
                return true;
        return false;
    }
    else {
        EqualityComparer<T> c = EqualityComparer<T>.Default;
        for(int i=0; i<_size; i++) {
            if (c.Equals(_items[i], item)) return true;
        }
        return false;
    }
}

Remove: 这个用在这里更废,先遍历找到item对应下标,再从数组中移除(需要将index后的元素复制到前面)

// Removes the element at the given index. The size of the list is
// decreased by one.
// 
public bool Remove(T item) {
    int index = IndexOf(item);
    if (index >= 0) {
        RemoveAt(index);
        return true;
    }

    return false;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值