Flutter - 在列表生成器中列出

Flutter - list inside a list builder

我对 flutter 没有多少经验。

我想将 language_tool library 用于 Dart 和 Flutter。

我创建了以下脚本:

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

class mainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return 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';

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

    print(correction);

    List<WritingMistake> mistakes = [];

    for (var m in correction) {
      //var mistake = m.issueDescription;

      WritingMistake mistake = WritingMistake(
        message: m.message,
        offset: m.offset,
        length: m.length,
        issueType: m.issueType,
        issueDescription: m.issueDescription,
        replacements: m.replacements,
      );

      mistakes.add(mistake);
    }

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

    return mistakes;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              color: Colors.red,
              height: 150.0,
              width: double.infinity,
              child:
                  Center(child: Text(text, style: TextStyle(fontSize: 20.0))),
            ),
            Text(
              '\n     Tap on the blue button to replace it in the message.\n',
            ),
            FutureBuilder(
              future: tool(text),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.data == null) {
                  return Container(
                    child: Center(
                      child: Text('Loading...'),
                    ),
                  );
                } else {
                  return SizedBox(
                    height: 200.0,
                    child: ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (BuildContext context, int index) {
                        return Container(
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Column(
                              children: [
                                Row(
                                  children: [
                                    Row(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        Text('   ' +
                                            (index + 1).toString() +
                                            ' '),
                                        Container(
                                          child: Padding(
                                            padding: const EdgeInsets.all(8.0),
                                            child: Text(text.substring(
                                                snapshot.data[index].offset,
                                                snapshot.data[index].offset +
                                                    snapshot
                                                        .data[index].length)),
                                          ),
                                          color: Colors.blue,
                                        ),
                                      ],
                                    ),
                                    Icon(
                                      Icons.arrow_forward,
                                    ),
                                    Text(snapshot.data[index].issueDescription)
                                  ],
                                ),

                                // Todo: Row with List of .replacements
                              ],
                            ),
                          ),
                          // snapshot.data[index].issueDescription),
                        );
                      },
                    ),
                  );
                }
              },
            ),
            Expanded(child: Container(color: Colors.grey))
          ],
        ),
      ),
    );
  }
}

目前看起来像这样:

我希望它变成这个屏幕中的样子,但我希望绿色容器源自 WritingMistake.replacements 列表(列表中的每个元素都是文本):

你知道我该怎么做吗?

花了几个小时做你想做的事。我的代码:

import 'dart:async';
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';

  static List<WritingMistake> mistakes = []; // Moved Here And Init Like Static

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

    print(correction);

    for (var m in correction) {
      //var mistake = m.issueDescription;

      WritingMistake mistake = WritingMistake(
        message: m.message,
        offset: m.offset,
        length: m.length,
        issueType: m.issueType,
        issueDescription: m.issueDescription,
        replacements: m.replacements,
      );

      mistakes.add(mistake);
    }

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

    return mistakes;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              color: Colors.red,
              height: 150.0,
              width: double.infinity,
              child: Center(
                  child: Text(text, style: const TextStyle(fontSize: 20.0))),
            ),
            const Text(
              '\n     Tap on the blue button to replace it in the message.\n',
            ),
            FutureBuilder(
              future: tool(text),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.data == null) {
                  return const Center(
                    child: Text('Loading...'),
                  );
                } else {
                  return SizedBox(
                    height: 200.0,
                    child: ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (BuildContext context, int mistakeIdIndex) {
                        return Container(
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Column(
                              children: [
                                Row(
                                  children: [
                                    Row(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        Text('   ' +
                                            (mistakeIdIndex + 1).toString() +
                                            ' '),
                                        Container(
                                          child: Padding(
                                            padding: const EdgeInsets.all(8.0),
                                            child: Text(text.substring(
                                                snapshot.data[mistakeIdIndex]
                                                    .offset,
                                                snapshot.data[mistakeIdIndex]
                                                        .offset +
                                                    snapshot
                                                        .data[mistakeIdIndex]
                                                        .length)),
                                          ),
                                          color: Colors.blue,
                                        ),
                                      ],
                                    ),
                                    const Icon(
                                      Icons.arrow_forward,
                                    ),
                                    Text(snapshot
                                        .data[mistakeIdIndex].issueDescription)
                                  ],
                                ),

                                // Todo: Row with List of .replacements
                                SizedBox(
                                  width: MediaQuery.of(context)
                                      .size
                                      .width, // Width = Screen Width
                                  height: 44,
                                  child: ListView.builder(
                                      itemCount: mistakes.length,
                                      scrollDirection: Axis.horizontal,
                                      shrinkWrap: true,
                                      itemBuilder: (BuildContext context,
                                          int replacementsListIndex) {
                                        return buildReplacements(mistakeIdIndex,
                                            replacementsListIndex);
                                      }),
                                )
                              ],
                            ),
                          ),
                          // snapshot.data[index].issueDescription),
                        );
                      },
                    ),
                  );
                }
              },
            ),
            Expanded(child: Container(color: Colors.grey))
          ],
        ),
      ),
    );
  }

  Widget buildReplacements(int mistakeIdIndex, int replacementsListIndex) {
    if (mistakes[replacementsListIndex].replacements!.length == null) {
      return const SizedBox(); // Return Empty If No Replacements Found, Just To Be Safe
    }

    // Check For Mistake ID - Remove This Will Cause A Problem with Displaying All Replacements Under All Words
    if (mistakeIdIndex == replacementsListIndex) {
      // If Only 1 Replacement, No Need To Create ListView.builder
      if (mistakes[replacementsListIndex].replacements!.length == 1) {
        return Container(
          margin: const EdgeInsets.all(4),
          padding: const EdgeInsets.all(8),
          decoration: const BoxDecoration(
              color: Color.fromARGB(255, 174, 213, 130)), // Green Color
          child: Text(
            mistakes[replacementsListIndex].replacements!.toString(),
            style: const TextStyle(),
            textAlign: TextAlign.center,
          ),
        );
      } 
      // Create ListView.builder to Create A Split Between Replacements To One Wrong-Word (Every Replacement Has It's Own Container With Green Background)
      else {
        return ListView.builder(
            itemCount: mistakes[replacementsListIndex].replacements!.length,
            scrollDirection: Axis.horizontal,
            shrinkWrap: true,
            itemBuilder: (context, index) {
              return Container(
                margin: const EdgeInsets.all(4),
                padding: const EdgeInsets.all(8),
                decoration: const BoxDecoration(
                    color: Color.fromARGB(255, 174, 213, 130)), // Green Color
                child: Text(
                  mistakes[replacementsListIndex]
                      .replacements![index]!
                      .toString(),
                  style: const TextStyle(),
                  textAlign: TextAlign.center,
                ),
              );
            });
      }
    } 
    // If Replacement Not For This Wrong-Word, Then Skip
    else {
      return const SizedBox();
    }
  }
}

和截图: