flutter 带有超链接的文本字段抖动

hyrbngr7  于 2023-03-04  发布在  Flutter
关注(0)|答案(3)|浏览(216)

我想创建一个文本字段,其中用户应该能够输入超链接到文本框中,超链接的颜色是蓝色的,超链接是可点击的。
是否有任何软件包或任何方式来实现它。请帮助!

r55awzrz

r55awzrz1#

这些软件包可以帮助你做到这一点。
link_text
flutter_linkify

ix0qys7i

ix0qys7i2#

当然-您可以使用LinkText软件包,网址为:https://pub.dev/packages/link_text

首先更新您的pubspec.yaml:

dependencies: 
  link_text: ^0.2.0

然后:

final String _hyperlink = 'StackOverflow https://stackoverflow.com/';

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: LinkText(
        _hyperlink,
        textAlign: TextAlign.left,
      ),
    ),
  );
}
zlhcx6iw

zlhcx6iw3#

这使用了一个很有技巧的解决方案,即将一个RichText小部件放在一个不可见的TextField的顶部:

import 'package:flutter/material.dart';
import 'package:link_text/link_text.dart';
import 'package:transparent_pointer/transparent_pointer.dart';
import 'package:url_launcher/url_launcher.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

TextEditingController textCont = TextEditingController();

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    textCont.addListener(() {
      setState(() {});
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Center(
            child: Stack(
          children: [
            TextField(
                maxLines: null,
                decoration: null,
                controller: textCont,
                autofocus: true,
                style: TextStyle(
                  letterSpacing: 0,
                  fontSize: 24,
                  height: null,
                  color: Colors.transparent,
                )),
            TransparentPointer(
              child: LinkText(
                textCont.text,
                textStyle:
                    TextStyle(fontSize: 24, height: null, letterSpacing: 0),
                linkStyle: TextStyle(
                    fontSize: 24,
                    color: Colors.blue,
                    letterSpacing: 0,
                    height: null),
                onLinkTap: (link) async {
                  final Uri _url = Uri.parse(link);
                  await launchUrl(_url, mode: LaunchMode.externalApplication);
                },
              ),
            ),
          ],
        )),
      ),
    );
  }
}

它使用已有的https://pub.dev/packages/link_text包来解析文本并返回RichText跨度,其中URL是可点击的链接。TransparentPointer(https://pub.dev/packages/transparent_pointer)小部件通过点击手势穿过堆栈,因此您仍然可以与LinkText小部件下方的TextField交互。
LinkText有点不灵活,所以要改变URL的样式,你必须派生它并编辑源代码。它用来检测URL的RegEx也有点限制,它要求所有URL都以http://或https://开头。Linkify可能是一个更好的解决方案,但我发现它处理人性化链接和样式URL的方式使它不可能很容易地与下面不可见的TextField对齐。
编辑:
如果您打算尝试这样做,还值得注意的是,为了使上述解决方案工作,您将不得不修改link_text包,以便在所有换行符中添加一个空格字符,这是由于RichText与Text相比呈现空行时存在一个bug(?):https://github.com/flutter/flutter/issues/121715

相关问题