美文网首页
Focus相关

Focus相关

作者: liboxiang | 来源:发表于2020-04-23 16:11 被阅读0次

备注:文中忽略了部分逻辑的,该文只是为了理解focus和unfocus过程,及怎么显示键盘和收起键盘的

focus.png

EditableText

Focus相关的类都是配合EditableText使用的

///EditableTextState class
 bool get _hasFocus => widget.focusNode.hasFocus;

由上面的流程图可以知道,EditableTextState initState的时候会监听widget.focusNode,当接收到通知的时候最终会调用_openOrCloseInputConnectionIfNeeded方法。在_openOrCloseInputConnectionIfNeeded方法内会判断_hasFocus,然后调用_openInputConnection()_closeInputConnectionIfNeeded()

  • _openInputConnection()会调用TextInputConnect的show(),然后调用TextInput的_show。最终会通过channel调起原生代码显示键盘
  • _closeInputConnectionIfNeeded()原理类似,最终会通过channel调起原生代码收起键盘

Focus相关

widget

  • class Focus extends StatefulWidget,node对应的是FocusNode。一个小部件,它管理[FocusNode]以允许将键盘焦点赋予该小部件及其后代。
  • class FocusScope extends Focus,node对应的是FocusScopeNode。FocusScope与Focus类似,但也可以作为其他Focus和FocusScope的边界将它们分组在一起。

两者的state的build方法中都会调用_focusAttachment.reparent();以将FocusNode和前面的node树连接起来。同时,两者的state的build方法中都使用到class _FocusMarker extends InheritedNotifier<FocusNode>
Focus和FocusScope的InheritedWidget标记。

reparent

由上面流程图可知,在EditableTextState的build方法中会调用FocusAttachment的reparent方法,将最近_FocusMarker中的FocusNode或者BuildOwner中focusManager的rootScope设置为node的parent,则将parent赋值给node._parent,并将node添加到parent的_children数组中。
由以上流程图可知,调用this.requestFocus(focusNode)方法,会将this设置为focusNode的parent。

requestFocus->_doRequestFocus

由流程图可知,对于FocusNode和FocusScopeNode,调用requestFocus方法,最终是分别调用各自的_doRequestFocus方法。_doRequestFocus方法中各自的逻辑如下:

  • FocusNode :调用_setAsFocusdChild方法,该方法的效果就如下图琐事,从图一变化到图二:


    图1
    图2.png

    总结起来就是将this层级上的所有FocusScopeNode分别放置到各自上一级FocusScopeNode的_focusedChildren数组中最后面。则设置为focusedChild值

///FocusScopeNode class
FocusNode get focusedChild {
    assert(_focusedChildren.isEmpty || _focusedChildren.last.enclosingScope == this, 'Focused child does not have the same idea of its enclosing scope as the scope does.');
    return _focusedChildren.isNotEmpty ? _focusedChildren.last : null;
  }

同时会调用_markAsDirty方法,在该方法内调node的_notify方法或者调_manager的_markNeedsUpdate

  • FocusScopeNode:查找最近的非FocusScopeNode类型的focusedChild(应该就是FocusNode类型)调用_doRequestFocus方法,如果没有则尝试聚焦最后一个FocusScopeNode

FocusManager

///当前focus的node
FocusNode get primaryFocus => _primaryFocus;
FocusNode _primaryFocus;
///请求focus,但是还没有focus的node
FocusNode _nextFocus;

由以上流程图可知,当focus的时候,会先将请求focus的node传递给_nextFocus,让后在调用node._notify()之前将_nextFocus赋值给_primaryFocus,并将_nextFocus置空。
当unfocus的时候,会将_primaryFocus和_nextFocus都置空,同时还会调用node._notify()

相关文章

  • Focus相关

    备注:文中忽略了部分逻辑的,该文只是为了理解focus和unfocus过程,及怎么显示键盘和收起键盘的 Edita...

  • 随笔

    阿里云香港 相关最多的是(滥用的话, 未来, 可能会出相关的): 翻墙, 之类的, 我的只focus在网站本身, ...

  • [WPF] IInputElement Focus Issue,

    Keyboard Focus and Logical Focus Keyboard Focus Keyboard ...

  • 学习计划

    2018-1-25leanback使用与解析TextView跑马灯原理Focus焦点相关原理 2018-1-22测...

  • Learn How to Savor the Moment

    Focus on Details 關注細節 Focus on Sensations 關注覺知 Focus on t...

  • FreshBulb-智慧灯泡

    Focus on intelligence and focus on light bulbs. This is a...

  • SAP Spartacus B2B ListComponent响

    SAP Spartacus B2B的List页面: 和回车键事件相关的实现: 调用栈:观察lock-focus.d...

  • 奋斗

    Focus on becoming more knowledgeable. Focus on gradual, c...

  • Focus

    I was arranged to write one article after the management ...

  • focus

    有感于平日忙忙碌碌,但是最终却是帮别人做test,费心费力,自己的事情还没做好。

网友评论

      本文标题:Focus相关

      本文链接:https://www.haomeiwen.com/subject/gmlxbhtx.html