Flutter — список внутри конструктора списков

У меня нет большого опыта с флаттером.

Я хотел бы использовать библиотека language_tool для 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))
          ],
        ),
      ),
    );
  }
}

И на данный момент это выглядит так:

Flutter — список внутри конструктора списков

И я хотел бы, чтобы это стало как на этом экране, но я хотел бы, чтобы зеленые контейнеры были получены из списка WritingMistake.replacements (с каждым элементом списка в виде текста):

Flutter — список внутри конструктора списков

Вы знаете, как я могу это сделать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Потратил несколько часов на то, что хотел. Мой код:

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();
    }
  }
}

И Скриншот:

привет, большое спасибо за ответ, ваш код идеально подходит для зеленых контейнеров, но теперь есть проблема: элементы в списке дублируются, когда я делаю горячую перезагрузку, и для каждой горячей перезагрузки добавляется дубликат. Я не могу понять, почему, вы можете решить это? пожалуйста

CastoldiG 01.04.2022 15:51

Это тема для другого вопроса, если вам помог мой ответ выше, то оцените его как правильный (галочка), а для нового вопроса создайте новый пост. Ссылка, которая может помочь с новым дефектом: stackoverflow.com/questions/60981183/…

Legend5366 01.04.2022 16:29

Другие вопросы по теме