UIGU源码分析9:DropDown

源码9:DropDown

DropDwon 主要就是为了实现下拉选择的功能

public class Dropdown : Selectable, IPointerClickHandler, ISubmitHandler, ICancelHandler
{

	...
	 protected internal class DropdownItem : MonoBehaviour, IPointerEnterHandler, ICancelHandler
	 {
	 		//Item显示的文字
     		[SerializeField]
            private Text m_Text;
            //Item显示的底图
            [SerializeField]
            private Image m_Image;
            //item的rectTransfom
            [SerializeField]
            private RectTransform m_RectTransform;
            //可点击的Toggle
            [SerializeField]
            private Toggle m_Toggle;
	 	...
	 }
	...

}

Dropdown 继承自Selectable,同时继承IPointerClickHandler, ISubmitHandler ICancelHandler 三个接口。

内板包含一个DropdownItem类 继承自MonoBehaviour和IPointerEnterHandler, ICancelHandler两个接口。

DropdownItem 就是我们点击的时候出现的下拉框选项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfepXPAs-1646668857105)(D:\UnityProjectSpace\BlogRecord\UGUI源码分析\Image\image-20220307231921151.png)]


DropdownItem 实现了IPointerEnterHandler 和 OnCancel

 public virtual void OnPointerEnter(PointerEventData eventData)
        {
            EventSystem.current.SetSelectedGameObject(gameObject);
        }

        public virtual void OnCancel(BaseEventData eventData)
        {
            Dropdown dropdown = GetComponentInParent<Dropdown>();
            if (dropdown)
                dropdown.Hide();
        }

当鼠标划入的时候 调用EventSystem的SetSelectedGameObject将本对象设置为选中的对象,表现就是Item对象的背景颜色变了。

当按键取消的时候 会调用dropdown的Hide 隐藏下拉列表


[SerializeField]
private int m_Value;
        
[SerializeField]
 private OptionDataList m_Options = new OptionDataList();

DropDwon中m_Value 是记录选中的m_Options里的值对应的索引Index

m_Value 是个属性设置值的时候会调用Set方法

    void Set(int value, bool sendCallback = true)
    {
        if (Application.isPlaying && (value == m_Value || options.Count == 0))
            return;

        m_Value = Mathf.Clamp(value, 0, options.Count - 1);
        RefreshShownValue();

        if (sendCallback)
        {
            // Notify all listeners
            UISystemProfilerApi.AddMarker("Dropdown.value", this);
            m_OnValueChanged.Invoke(m_Value);
        }
    }

    public void RefreshShownValue()
    {
        OptionData data = s_NoOptionData;

        if (options.Count > 0)
            data = options[Mathf.Clamp(m_Value, 0, options.Count - 1)];

        if (m_CaptionText)
        {
            if (data != null && data.text != null)
                m_CaptionText.text = data.text;
            else
                m_CaptionText.text = "";
        }

        if (m_CaptionImage)
        {
            if (data != null)
                m_CaptionImage.sprite = data.image;
            else
                m_CaptionImage.sprite = null;
            m_CaptionImage.enabled = (m_CaptionImage.sprite != null);
        }

当设置m_value的时候会调用RefreshShownValue 方法 并且发送m_OnValueChanged事件

RefreshShownValue 主要是刷新DropDown的显示 取出当前m_value对应的值的(图片 和 Text)设置到DropDown中


当点击的时候会调用OnPointerClick 进行列表的显示Show (OnSubmit 调用的也是一样)

 public virtual void OnPointerClick(PointerEventData eventData)
        {
            Show();
        }

Show的代码比较长 就不贴了 主要操作如下

  1. 调用SetupTemplate方法,设置模板。为Item添加DropdownItem,为m_Template添加Canvas,设置overrideSorting为true,sortingOrder为30000,为选项表尽可能的显示在前面,然后添加GraphicRaycaster,CanvasGroup组件,为了接受鼠标事件。
  2. CreateDropdownList,实例化DropDown实例,SetParent设置父节点
  3. 获得DropdownItem,以DropdownItem为模板创建Item,并填充数据。设置toggle状态,添加toggle的onValueChanged事件。
  4. 根据Item的数量设置Content的尺寸,Content是ScrollRect里的内容对象。并且如果DropDownList的高度大于Content的高度,便修正他的高度与Content相同。
  5. 然后判断DropDownList的四个角,是否超出了rootCanvas(Dropdown最上层的Canvas)的边界,便翻转DropDownList(DropDownList的四个角超出了rootCanvas的最小值,便往上弹出,否则往下弹出),然后设置Item的位置和尺寸。
  6. 通过调整CanvasGroup的alpha值,渐变显示Dropdown List,并将m_Template和itemTemplate设置为无效的。
  7. 调用CreateBlocker创建Blocker。Blocker在rootCanvas下一级,尺寸与rootCanvas相同,sortingOrder比Dropdown List的小1(29999)。添加了Image组件,颜色为全透明,添加了Button组件,添加了onClick的监听,回调Hide方法。由此我们可知道Blocker是用于阻挡住鼠标事件,即Dropdown List显示时,点击选项表以外的区域,都只是隐藏选项表,不会触发其他的组件。
  8. Hide方法,Alpha渐变隐藏Dropdown List,并在渐变结束后Destroy所有的Item和Dropdown List。接着DestroyBlocker。最后设置本对象为Select(高亮状态)。

Dropdown重写了Start方法,新建了一个FloatTween类型的TweenRunner变量m_AlphaTweenRunner并初始化,这个变量在显示/隐藏选项表(Dropdown List)的时候执行透明度渐变效果。

    protected override void Start()
    {
        m_AlphaTweenRunner = new TweenRunner<FloatTween>();
        m_AlphaTweenRunner.Init(this);
        base.Start();

        RefreshShownValue();
    }

   private void AlphaFadeList(float duration, float start, float end)
    {
        if (end.Equals(start))
            return;

        FloatTween tween = new FloatTween {duration = duration, startValue = start, targetValue = end};
        tween.AddOnChangedCallback(SetAlpha);
        tween.ignoreTimeScale = true;
        m_AlphaTweenRunner.StartTween(tween);
    }

猜你喜欢

转载自blog.csdn.net/NippyLi/article/details/123342945
今日推荐