我正在实现类似由分隔符分隔的热(可点击)文本的面包屑痕迹之类的东西,并且如果需要换行,我希望整个内容可以根据需要换行在热文本的中间。因为面包屑是链接,所以它们必须是小部件的集合,但是在 Wrap 对象中显示它们会导致它们在每个小部件的基础上换行,因此永远不会位于面包屑链接的中间。
我尝试使用 Row(行)、Row 行(最后一行展开)来执行此操作,尝试使用 Text 对象上的 softWrap 等属性、“富文本”等。我四处寻找这个用例,并将其发布到另一个论坛。看来这在成熟的应用程序开发框架中应该是可能的。
您可以将
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,
],
),
),
),
),
);
}
}
供您参考:对于这种情况,您也可以使用
。RichText
如果您尝试我的演示代码,如果您单击文本,它将显示一条日志“clicked: $crumbText”
参考:
经过快速研究,发现
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,
],
),
),
),
),
);
}
}
可能的问题
我没有看到
有TapGestureRecognizer
来管理链接的点击区域,因此用户需要在tapTargetSize
内精确点击。TextSpan
推荐
将行高添加到
将最大限度地减少错过点击的情况。TextSpan
参考: