系列
UGUI源码分析系列总览
相关前置:
UGUI EventSystem源码分析
UGUI源码分析:Selectable交互组件的基类
UGUI源码分析:开关组件Toggle与ToggleGroup
UML图一览
Dropdown
BaseClass: Selectable
Interface:IPointerClickHandler,ISubmitHandler,ICancelHandler
Intro: UGUI中下拉列表组件
- IPointerClickHandler:点击事件的响应接口
- ISubmitHandler:Submit按键点击事件的响应接口,Submit是可以在Project Settings中的Input输入设置。当组件被选中时(“选中”的详细介绍请看Selectable)可响应Submit事件。
- ICancelHandler :Cancel按键点击事件的响应接口,原理同Submit接口,此按键代表取消操作
Dropdown,是UGUI中下拉列表功能组件。它属于直接介绍的组件的混合体,Dropdown组件中运用到了Text、Toggle、Scrollbar、ScrollRect组件,更具具体需求可以舍弃除Toggle之外的组件进行自己的改造。
属性介绍
- Interactable:是否可被交互(false时无法通过EventSystem进行交互)
- Transition:状态变化过渡模式(相关详情)
- Navigation:导航(相关详情)
- Template :下拉列表模板
- Caption Text :当前选中的选项文字描述
- Caption Image :当前选中的选项图片描述
- Item Text :用于绑定DropdownItem 的Text组件
- Item Image :用于绑定DropdownItem的 Image组件
- Value :当前选择索引
- Options :选项数据list
- On Value Changed :value变化的事件监听
初始化
Dropdown的初始化过程仅有一个Awake,做了帮助实现动画过渡模块初始化。
protected override void Awake()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
m_AlphaTweenRunner = new TweenRunner<FloatTween>();
m_AlphaTweenRunner.Init(this); // 初始化渐变模块
if (m_CaptionImage)
m_CaptionImage.enabled = (m_CaptionImage.sprite != null);
if (m_Template)
m_Template.gameObject.SetActive(false);
}
Show()
由事件为导向的触发:在点击事件与确定事件中都是相同的处理,执行了 Show() 方法显示下拉列表
public virtual void OnPointerClick(PointerEventData eventData)
{
Show();
}
public virtual void OnSubmit(BaseEventData eventData)
{
Show();
}
Show()方法:显示下拉列表的方法,也是整个Dropdown组件最关键的方法,它做到了以下几点内容
- 若没有对列表模板(Template)进行过初始化设置便进行初始化:检测模板是否符合要求(Item含有Toggle组件、父级不是RectTransform、ItemText与ItemImage如果存在必须在Item内部),为ToggleItem添加DropdownItem组件并做相关绑定,将列表模板处于UI的最高层(
popupCanvas.sortingOrder = 30000;
)
public void Show()
{
if (!IsActive() || !IsInteractable() || m_Dropdown != null)
return;
//初始状态时validTemplate为false来触发对于列表模板的初始化设置
if (!validTemplate)
{
//模板初始化方法:检测并设置模板,初始化模板绑定相关组件并调整模板UI层级,若没有通过检查则模板标记为不可用状态。
SetupTemplate();
//若检测不通过则无法正常显示下拉列表
if (!validTemplate)
return;
}
....
}
//模板初始化
private void SetupTemplate()
{
validTemplate = false;
if (!m_Template)
{
return;
}
GameObject templateGo = m_Template.gameObject;
templateGo.SetActive(true);
Toggle itemToggle = m_Template.GetComponentInChildren<Toggle>();
validTemplate = true;
//各种条件检查模板是否满足要求
if (!itemToggle || itemToggle.transform == template)
{
validTemplate = false;
}
else if (!(itemToggle.transform