Flutter陌生而又熟悉组件-Semantics

2,915 阅读4分钟

概括

Semantics可能是Flutter中比较陌生的组件,如果不是遇见过,开发中大多不会想到使用Semantics。 构造如下:

  Semantics({
    Key? key,
    Widget? child,
    bool container = false,
    bool explicitChildNodes = false,
    bool excludeSemantics = false,
    bool? enabled,
    bool? checked,
    bool? selected,
    bool? toggled,
    bool? button,
    bool? slider,
    bool? link,
    bool? header,
    bool? textField,
    bool? readOnly,
    bool? focusable,
    bool? focused,
    bool? inMutuallyExclusiveGroup,
    bool? obscured,
    bool? multiline,
    bool? scopesRoute,
    bool? namesRoute,
    bool? hidden,
    bool? image,
    bool? liveRegion,
    int? maxValueLength,
    int? currentValueLength,
    String? label,
    String? value,
    String? increasedValue,
    String? decreasedValue,
    String? hint,
    String? onTapHint,
    String? onLongPressHint,
    TextDirection? textDirection,
    SemanticsSortKey? sortKey,
    SemanticsTag? tagForChildren,
    VoidCallback? onTap,
    VoidCallback? onLongPress,
    VoidCallback? onScrollLeft,
    VoidCallback? onScrollRight,
    VoidCallback? onScrollUp,
    VoidCallback? onScrollDown,
    VoidCallback? onIncrease,
    VoidCallback? onDecrease,
    VoidCallback? onCopy,
    VoidCallback? onCut,
    VoidCallback? onPaste,
    VoidCallback? onDismiss,
    MoveCursorHandler? onMoveCursorForwardByCharacter,
    MoveCursorHandler? onMoveCursorBackwardByCharacter,
    SetSelectionHandler? onSetSelection,
    VoidCallback? onDidGainAccessibilityFocus,
    VoidCallback? onDidLoseAccessibilityFocus,
    Map<CustomSemanticsAction, VoidCallback>? customSemanticsActions,
  }) : this.fromProperties(...)

细数一下大致有54个参数????? 在这里插入图片描述 翻译过来就是:一个widget,用以描述widget树的具体语义。使用辅助工具、搜索引擎和其他语义分析软件来确定应用程序的含义。 看完之后更迷惑? Semantics中文翻译为语义学、语义论,主要起辅助作用,多用于分析屏幕上的内容,就是将程序翻译成大白话,可以帮助有视觉障碍的人士更好的使用软件。

Semantics从另一方面讲是开发者最熟悉的组件? 在这里插入图片描述 上述各种属性在常用的各种组件中多多少少都有涉及,基本上开发者经常使用的组件都在Semantics上找到定位。

使用

属性解释

属性含义
child子组件
container是否在引入一个新的语义节点
explicitChildNodes是否强制显示子Widget的语义信息
excludeSemantics是否排除子Widget中的语义
enabled是否可用
checkedCheckBox是否被勾选
selected是否选中
toggledtoggle是否切换
button是否是Button
slider是否是slider
link是否是link
header是否是header
textField是否是textField
readOnly是否制度
focusable是否可聚焦
focused是否聚焦
inMutuallyExclusiveGroup是否兼容
obscured是否模糊
multiline是否多行
scopesRoute是否是声明路由名
namesRoute是否包含路由的语义标签
hidden是否隐藏
image是否是image
liveRegion是否活跃
maxValueLength最大长度
currentValueLength当前长度
labelWidget的文本描述
value
increasedValue增值
decreasedValue减值
hint提示
onTapHint点击提示
onLongPressHint长按提示
textDirection文本方向
sortKey排序
tagForChildren子节点标签
onTap点击事件
onLongPress长按事件
onScrollLeft左滑事件
onScrollRight右滑事件
onScrollUp上滑事件
onScrollDown下滑事件
onIncrease增值事件
onDecrease减值事件
onCopycopy
onCutcut
onPastepaste
onDismissdismiss
onMoveCursorForwardByCharacter字符光标前移
onMoveCursorBackwardByCharacter字符光标后移
onSetSelection选择事件
onDidGainAccessibilityFocus获取焦点
onDidLoseAccessibilityFocus失去焦点
customSemanticsActions自定义事件

翻译的不准确,见谅!

分类

  • Semantics 一个widget,用以描述widget树的具体语义。使用辅助工具、搜索引擎和其他语义分析软件来确定应用程序的含义。
  • MergeSemantics 合并其后代语义的widget。
  • ExcludeSemantics 删除其后代所有语义的widget

使用

          Flexible(
            child: Semantics(
              label: MaterialLocalizations.of(context).selectYearSemanticsLabel,
              excludeSemantics: true,
              button: true,
              child: Container(
                height: _subHeaderHeight,
                 child: InkWell(
                     onTap: widget.onTitlePressed,
                     ...

解释InkWell语言,即读出屏幕中此按钮是什么样按钮

        // dayWidget
        child: Semantics(
              label: '${localizations.formatDecimal(day)}, ${localizations.formatFullDate(dayToBuild)}',
              selected: isSelectedDay,
              excludeSemantics: true,
              child: dayWidget,
            ),
            ...

dayItems.add(dayWidget);

这是Flutter自带的日历中一段代码,dayWidget是日历中每一天的组件,最后将一个月中所有日期添加进dayItems列表中集中显示,则呈现出某月的日历。 label: 'localizations.formatDecimal(day),{localizations.formatDecimal(day)}, {localizations.formatFullDate(dayToBuild)}',是解释了这一天是哪一天,excludeSemantics:true,则表示删除其后代所有语义的widget,若还有子控件还有语义,不承认,无效。

...
    return MergeSemantics(
      child: Semantics(
        enabled: widget.enabled,
        button: true,
        child: InkWell(
          onTap: widget.enabled ? handleTap : null,
          canRequestFocus: widget.enabled,
          mouseCursor: effectiveMouseCursor,
          child: item,
        ),
      )
    );
    ...

这是PopupMenuItem部分代码,MergeSemantics即将子widget语义合并,若PopupMenuItem中还有item,则合为同一个。

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      showSemanticsDebugger:true,
      ...

若showSemanticsDebugger设为false和true,则会出现不同的视图:

在这里插入图片描述在这里插入图片描述

明显可以看出当showSemanticsDebugger为true的时候,视图明显不一样,虽不够美观,但更加容易识别和操作,这也就解释了为什么Semantics通常用于帮助视觉有障碍的人士。

文中很多属性解释不清楚,使用方法描述不清晰,归根结底还是不熟悉,以后还需多多探索。截图中数据均为假数据,不可较真。