有没有办法让热文本(链接)换行(需要时在链接内)?

问题描述 投票:0回答:2

我正在实现类似由分隔符分隔的热(可点击)文本的面包屑痕迹之类的东西,并且如果需要换行,我希望整个内容可以根据需要换行在热文本的中间。因为面包屑是链接,所以它们必须是小部件的集合,但是在 Wrap 对象中显示它们会导致它们在每个小部件的基础上换行,因此永远不会位于面包屑链接的中间。

screen shot of desired vs. actual behavior

我尝试使用 Row(行)、Row 行(最后一行展开)来执行此操作,尝试使用 Text 对象上的 softWrap 等属性、“富文本”等。我四处寻找这个用例,并将其发布到另一个论坛。看来这在成熟的应用程序开发框架中应该是可能的。

flutter word-wrap
2个回答
0
投票

您可以将

Text.rich()
用于内联小部件/文本案例。对于富文本,我们可以使用带有文本的内联小部件,无需任何换行符。

我提供简单的代码来展示

Text.rich()
的工作原理:

import 'package:flutter/material.dart';

class InlineLinkPage extends StatelessWidget {
  const InlineLinkPage({super.key});

  @override
  Widget build(BuildContext context) {
    // Crumb separator.
    const TextSpan separator = TextSpan(text: ' | ');

    // Build crumb with [WidgetSpan] with the parameter [text] as [String].
    // 
    // Usage Example: 
    // ```
    // crumb('First Breadcrumb');
    // ```
    WidgetSpan crumb(String text) {
      return WidgetSpan(
        // This alignment handle vertical position of the [WidgedSpan]
        alignment: PlaceholderAlignment.middle,
        // [GestureDetector] can be changed to [TextButton], [ElevatedButton],
        // [OutlinedButton], or anything to handle the link.
        child: GestureDetector(
          // Handle your link function here
          onTap: () {
            // If the crumb clicked, the log will show
            // 'clicked: This is the .... crumb'.
            print('clicked: $text');
          },
          child: Text(text),
        ),
      );
    }

    return Scaffold(
      appBar: AppBar(title: const Text('Inline Link Page')),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Text.rich(
            TextSpan(
              children: [
                crumb('This is the first crumb'),
                separator,
                crumb('This is the second crumb'),
                separator,
                crumb('This is the third crumb'),
                separator,
                crumb('This is the fourth crumb'),
                separator,
                crumb('etc'),
                separator,
              ],
            ),
          ),
        ),
      ),
    );
  }
}

输出

Inline text and widget demonstration

供您参考:对于这种情况,您也可以使用

RichText

如果您尝试我的演示代码,如果您单击文本,它将显示一条日志“clicked: $crumbText”

参考:


0
投票

经过快速研究,发现

TextSpan
具有在
recognizer
中提供手势识别器的属性。该识别器可以填充许多手势识别器,例如与
TapGestureRecognizer
中的
onTap
具有类似能力的
GestureDetector

我提供了示例代码来说明其工作原理:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class InlineLinkPage extends StatelessWidget {
  const InlineLinkPage({super.key});

  @override
  Widget build(BuildContext context) {
    // Crumb separator.
    const TextSpan separator = TextSpan(text: ' | ');

    // Build crumb with [TextSpan] with the parameter [text] as [String].
    //
    // Usage Example:
    // ```
    // crumb('First Breadcrumb');
    // ```
    TextSpan crumb(String text) {
      // A function that triggered when the text is tapped.
      void handleTap() {
        // Write your logical [crumb] behavior when user tap the [crumb] here...
        print('Clicked: $text');
      }

      // Initialize [GestureRecognizer] for TextSpan. This is for detect tap
      // from user. 
      // 
      // In this case [recognizer] use [TapGestureRecognizer], The way it work 
      // is the same as [onTap] in [GestureDetector].
      // 
      // There's other option for [recognizer] like [LongPressGestureRecognizer()..onLongPress],
      // for detect long press on the widget.
      final recognizer = TapGestureRecognizer()..onTap = handleTap;

      return TextSpan(
        text: text,
        recognizer: recognizer,
      );
    }

    return Scaffold(
      appBar: AppBar(title: const Text('Inline Link Page')),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: RichText(
            text: TextSpan(
              style: const TextStyle(color: Colors.black87),
              children: [
                crumb('This is first crumb'),
                separator,
                crumb('This is the second crumb'),
                separator,
                crumb('This is the third crumb'),
                separator,
                crumb('This is the fourth crumb'),
                separator,
                crumb('etc'),
                separator,
              ],
            ),
          ),
        ),
      ),
    );
  }
}

输出

Inline functional text

可能的问题

我没有看到

TapGestureRecognizer
tapTargetSize
来管理链接的点击区域,因此用户需要在
TextSpan
内精确点击。

推荐

将行高添加到

TextSpan
将最大限度地减少错过点击的情况。

参考:

© www.soinside.com 2019 - 2024. All rights reserved.