如何在 flutter 中使用对 RichText 的关注?

How to use focus on RichText in flutter?

我有一个这样的文本范围列表

var spans = [
TextSpan(text: content, style: style),
TextSpan(text: content, style: style) 
//and 100 more
]   

我正在像这样将其加载到 SingleChildScrollView 中。

        SingleChildScrollView(
        controller: scrollController,
        child: Text.rich(
                  TextSpan(children: spans),
                       ),
                     )        

现在我的问题是如何在 TextSpan 列表之间转移焦点?。假设我想在屏幕顶部的 spans 列表中的位置 10 加载 TextSpan 而无需手动滚动。

您可以在每个 TextSpan 旁边添加一个 WidgetSpan,这样您就可以为它分配一个 key 属性,即 GlobalKey所以你可以访问它的 BuildContext 来调用方法 Scrollable.ensureVisible().

这是受 启发的代码示例:

class ScrollToTextSpanPage extends StatefulWidget {
  const ScrollToTextSpanPage({Key? key}) : super(key: key);

  @override
  State<ScrollToTextSpanPage> createState() => _ScrollToTextSpanPageState();
}

class _ScrollToTextSpanPageState extends State<ScrollToTextSpanPage> {
  final _keys = List<GlobalKey>.generate(
    _kTextBlocks.length,
    (_) => GlobalKey(),
  );

  void _goToSpan(int spanIndex) {
    Scrollable.ensureVisible(
      _keys[spanIndex].currentContext!,
      alignment: 0.2,
      duration: const Duration(milliseconds: 300),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Scroll to TextSpan'),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () => _goToSpan(8),
        label: const Text('Go to span 8'),
        icon: const Icon(Icons.navigate_next),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Text.rich(
          TextSpan(
            children: [
              for (int i = 0; i < _kTextBlocks.length; i++) ...[
                WidgetSpan(child: SizedBox(key: _keys[i])),
                TextSpan(
                  text: 'Span $i\n',
                  style: const TextStyle(fontWeight: FontWeight.bold),
                  children: [
                    TextSpan(
                      text: '${_kTextBlocks[i]}\n\n',
                      style: const TextStyle(fontWeight: FontWeight.normal),
                    ),
                  ],
                ),
              ],
            ],
          ),
        ),
      ),
    );
  }
}

Try the sample on DartPad