Flutter -> 来自单词列表的 RichText

Flutter -> RichText From a List of Words

我对 flutter 没有多少经验。

我正在为 Dart 和 Flutter 使用 language_tool 库 (https://pub.dev/packages/language_tool)。

我想要错误列表中出现的单词,这些单词是由于字符串文本中的 language_tool 而发现的语法错误的单词 = 'Henlo i am Gabriele';

为红色并带有下划线,(即使我决定更改字符串文本也会发生这种情况)。

- 这是我目前的代码:

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

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

class mainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Chat(),
    );
  }
}

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

  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {
  String text = 'Henlo i am Gabriele';
  List<WritingMistake> mistakes = [];
  List Error = [];

  void tool(String text) async {
    var tool = LanguageTool();
    var result = tool.check(text);
    var correction = await result;

    for (var m in correction) {
      WritingMistake mistake = WritingMistake(
        message: m.message,
        offset: m.offset,
        length: m.length,
        issueType: m.issueType,
        issueDescription: m.issueDescription,
        replacements: m.replacements,
      );

      mistakes.add(mistake);
    }

    for (var mistake in mistakes) {
      var error =
          text.substring(mistake.offset!, mistake.offset! + mistake.length!);
      Error.add(error);
    }

    print(mistakes.length);
    print(mistakes);
    print(Error);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView(
          children: [
            Container(
              color: Colors.red,
              height: 150.0,
              width: double.infinity,
              child: Center(
                  child: Text(text, style: const TextStyle(fontSize: 20.0))),
            ),
            Container(
              color: Colors.white60,
              height: 150.0,
              width: double.infinity,
            ),
          ],
        ),
      ),
    );
  }
}

这是这段代码的输出:

最后,这是我想要的输出:

希望我说清楚了,希望有人能帮助我。

谢谢:)

这应该可行,但需要重构。 我还将您的功能从“工具”更新为“getErrors” 我实现 FutureBuilder 是因为我们需要使用异步进程 tool.check(text) 检查字符串并 return 更正错误。
我找不到制作线性下划线的方法,您可以在下划线中注意到一些上下。

编辑: 我更新了代码,现在它可以工作了。 PS:单词之间的 space 是使用 SizedBox 手动制作的。如果您找到并分享更舒适的解决方案,我将不胜感激。
我还添加了一个带有加载文本的字符串,同时库正在查找字符串中的一些错误。

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

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

class mainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Chat(),
    );
  }
}

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

  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {
  String text = 'Henlo Manuel, wher is Gabriele';

  Future<List<String>> getErrors(String text) async {
    List<WritingMistake> mistakes = [];
    List<String> Error = [];
    var tool = LanguageTool();
    var result = tool.check(text);
    var correction = await result;

    for (var m in correction) {
      WritingMistake mistake = WritingMistake(
        message: m.message,
        offset: m.offset,
        length: m.length,
        issueType: m.issueType,
        issueDescription: m.issueDescription,
        replacements: m.replacements,
      );

      mistakes.add(mistake);
    }

    for (var mistake in mistakes) {
      var error =
          text.substring(mistake.offset!, mistake.offset! + mistake.length!);
      Error.add(error);
    }

    print(mistakes.length);
    print(mistakes);
    print(Error);

    return Error;
  }

  // Render widget with final string
  Future<Widget> _printWordWithError(String string) async {
    // Call your function to generate some errors
    final List<String> errors = await getErrors(string);
    final List<String> wordsList = string.split(' ');

    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ...List.generate(
          wordsList.length,
          (i) {
            final String word = wordsList[i];
            final hasSpace = i < wordsList.length - 1;
            if (errors.contains(word)) {
              return Row(
                children: [
                  getStyledErrorText("$word"),
                  hasSpace ? const SizedBox(width: 4) : Container()
                ],
              );
            } else {
              return Row(
                children: [
                  getStyledValidText("$word"),
                  hasSpace ? const SizedBox(width: 4) : Container()
                ],
              );
            }
          },
        ),
      ],
    );
  }

  // Render single text with error style
  Widget getStyledErrorText(String string) {
    return Text(
      string,
      style: const TextStyle(
        fontSize: 20,
        color: Colors.red,
        decorationStyle: TextDecorationStyle.solid,
        decorationColor: Colors.red,
        decoration: TextDecoration.underline,
      ),
    );
  }

  // Render single text without error style
  Widget getStyledValidText(String string) {
    return Text(
      string,
      style: const TextStyle(
        fontSize: 20,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView(
          children: [
            Container(
              color: Colors.red,
              height: 150.0,
              width: double.infinity,
              child: Center(
                  child: Text(text, style: const TextStyle(fontSize: 20.0))),
            ),
            Container(
              color: const Color.fromARGB(153, 112, 112, 112),
              height: 150.0,
              width: double.infinity,
              child: FutureBuilder(
                future: _printWordWithError(text),
                builder: (ctx, AsyncSnapshot<Widget> text) {
                  if (text.data == null) {
                    return const Center(
                      child: Text(
                        "Loading string",
                        style: TextStyle(fontSize: 20),
                      ),
                    );
                  }
                  return Center(
                    child: text.data,
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}