如何将 Flutter 小部件划分为语义树中的单独节点

Chr*_*ore 2 accessibility flutter

我创建了一个自定义小部件来表示 a 中的图块ListView,下面包含其示例。该图块包含一个Inkwell,以便可以点击它。该图块还包含一个MaterialButton. 我已相应地包装了所有内容Semantics,但每当启用 Talkback 并点击该图块时,整个图块都会突出显示。这使得里面的按钮无法点击。

如何将每个节点Widget视为Semantics树中的单个节点?文档MergeSemanticshttps://api.flutter.dev/flutter/widgets/MergeSemantics-class.html)似乎暗示Widgets应该单独处理,除非它们包装在MergeSemantics.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListView(
          children: [Tile()],
        ),
      ),
    );
  }
}

class Tile extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Padding(
        padding: EdgeInsets.only(top: 12),
        child: InkWell(
          onTap: () => print('Tile tapped'),
          child: _tile(),
        ),
      );

  Widget _tile() => Container(
        padding: EdgeInsets.all(12),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(5)),
          border: Border.all(color: Colors.grey, width: 1),
          shape: BoxShape.rectangle,
        ),
        child: Row(
          children: [
            _textAndCount(),
            SizedBox(width: 12),
            _button(),
          ],
        ),
      );

  Widget _textAndCount() => Expanded(
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              child: _text(),
            ),
            _count(),
          ],
        ),
      );

  Widget _text() => Text(
        'text',
        overflow: TextOverflow.ellipsis,
        maxLines: 2,
        textAlign: TextAlign.start,
      );

  Widget _count() =>
      Padding(
        padding: EdgeInsets.only(top: 12),
        child: Row(
          children: [
            Semantics(
              label: '0 things',
              child: ExcludeSemantics(
                child: Container(
                  padding: EdgeInsets.symmetric(horizontal: 12),
                  decoration: BoxDecoration(
                    shape: BoxShape.rectangle,
                    color: Colors.grey,
                    borderRadius: BorderRadius.circular(10),
                  ),
                  child: Text('0'),
                ),
              ),
            ),
          ],
        ),
      );

  Widget _button() => Semantics(
        label: 'button',
        button: true,
        child: Tooltip(
          message: 'button',
          excludeFromSemantics: true,
          child: ExcludeSemantics(
            child: MaterialButton(
              onPressed: () => print('Button tapped'),
              child: Container(
                child: SizedBox(
                  height: 44,
                  width: 44,
                  child: Icon(Icons.add),
                ),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey, width: 2),
                  shape: BoxShape.circle,
                ),
              ),
            ),
          ),
        ),
      );
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ore 5

在 Flutter GitHub 存储库上发布问题并得到以下回复: https: //github.com/flutter/flutter/issues/54725

结果Semantics小部件有一个container属性,当设置为 true 时,包装对象将充当树中自己的节点Semantics