系列
UGUI源码分析系列总览
相关前置:
UGUI EventSystem源码分析
UGUI源码分析:Selectable交互组件的基类
UGUI源码分析:Text与Outline的具体实现
UML图一览
InputField
BaseClass: Selectable
Interface: IUpdateSelectedHandler,IXXXDragHandler,IPointerClickHandler,ISubmitHandler,ICanvasElement,ILayoutElement
Intro: UGUI中输入框组件组件
- IUpdateSelectedHandler:刷新当前被选中物体事件监听,帧刷新
- IXXXDragHandler:三个拖拽接口,这里就简写成这样,监听整个拖拽过程(开始,拖拽,结束)。
- IPointerClickHandler: 点击事件接口
- ISubmitHandler: Submit按键点击事件的响应接口,Submit是可以在Project Settings中的Input输入设置。当组件被选中时(“选中”的详细介绍请看Selectable)可响应Submit事件。
- ICanvasElement :Canvas元素(重建接口),当Canvas发生更新时重建(void Rebuild)
- ILayoutElement:布局相关接口
InputField,是UGUI中输入文本框组件。它提供了丰富的输入文本属性来实现输入功能,并提供了两个监听事件OnValueChanged(文本变化时响应)OnEndEdit(完成编辑时响应)。
属性介绍
- Interactable:是否可被交互(false时无法通过EventSystem进行交互)
- Transition:状态变化过渡模式(相关详情)
- Navigation:导航(相关详情)
- Text Component :文本组件
- Text :文本内容
- Character Limit :字符长度限制
- Content Type :内容类型(数字、邮箱、字母、密码共十种类型选择)
- Line Type :行类型(单行、多行)
- Placeholder :占位Text组件,当无内容时显示该组件
- Caret Blink Rate :光标闪烁频率
- Caret Width :光标宽度
- CustomCaretColor :自定义光标颜色开关
- Selection Color :选中区域颜色
- Hide Mobile Input:隐藏输入框开关
- On Value Changed:文本发生变化的事件监听
- On End Edit :完成编辑的事件监听
为了呈现出输入框的交互效果,InputField的代码量非常的大(2400+行)是UGUI组件中内容量最大的组件,逻辑并不复杂,只在于它实现的输入功能细节很多(例如各种输入要求限制,光标效果,拖拽选中区域…)初看源码会有一种懵的感觉。所以本章就针对其基本的输入交互流程来分析其实现原理,不发散去关注它各个细节的实现。
初始化
一如既往,阅读源码的最好方式就是先从生命周期开始。
Enable阶段:主要是向Text组件注册了重建前(脏标记)时的事件监听。并执行了UpdateLabel方法,相应的事件中也包含了UpdateLabel方法,该方法便是我们重点关注的地方。
protected override void OnEnable()
{
base.OnEnable();
if (m_Text == null)
m_Text = string.Empty;
m_DrawStart = 0;
m_DrawEnd = m_Text.Length;
if (m_CachedInputRenderer != null) m_CachedInputRenderer.SetMaterial(m_TextComponent.GetModifiedMaterial(Graphic.defaultGraphicMaterial), Texture2D.whiteTexture);
//向Text组件注册事件监听,主要当Graphic进行顶点与材质的重建标记时会执行相应的监听事件
if (m_TextComponent != null)
{
m_TextComponent.RegisterDirtyVerticesCallback(MarkGeometryAsDirty);
m_TextComponent.RegisterDirtyVerticesCallback(UpdateLabel);
m_TextComponent.RegisterDirtyMaterialCallback(UpdateCaretMaterial);
UpdateLabel();//更新文本
}
}
Disable阶段:非常普通地做了一些清理工作。
protected override void OnDisable()
{
// 关闭携程
m_BlinkCoroutine = null;
//将各种属性做无效处理
DeactivateInputField();
//注销Text中的事件监听
if (m_TextComponent != null)
{
m_TextComponent.UnregisterDirtyVerticesCallback(MarkGeometryAsDirty);
m_TextComponent.UnregisterDirtyVerticesCallback(UpdateLabel);
m_TextComponent.UnregisterDirtyMaterialCallback(UpdateCaretMaterial);
}
CanvasUpdateRegistry.UnRegisterCanvasElementForRebuild(this);
if (m_CachedInputRenderer != null)
m_CachedInputRenderer.Clear();
//清除网格
if (m_Mesh != null)
DestroyImmediate(<