Динамически создавать список с настраиваемым количеством виджетов в строке

#flutter #dart

#flutter #dart

Вопрос:

У меня есть следующий список, который составлен в нужном мне формате, где это 3 виджета в строке.

Но это жестко запрограммировано.

Как я мог зациклить это или какое-то более чистое решение, чтобы я мог повторять это столько раз, сколько захочу?

Как и сейчас, у меня есть 4 строки. Скажем, я хочу 10 строк, по 3 виджета в каждой, я не хочу копировать, вставляя это 10 раз

кроме того, я не знаю, сколько строк я собираюсь получить. Это зависит от некоторых внешних данных. Могу ли я получить некоторые рекомендации? Спасибо.

 ListView(
    children: [
        Padding(
            padding: const EdgeInsets.only(right: 8, top: 8),
            child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                    Expanded(child: CustomWidget('test', 0)), // these numbers are indexes which differs for each widget
                    Expanded(child: CustomWidget('test', 1)),
                    Expanded(child: CustomWidget('test', 2)),
                ],
            ),
        ),
        Padding(
            padding: const EdgeInsets.only(right: 8, top: 8),
            child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                    Expanded(child: CustomWidget('test', 3)),
                    Expanded(child: CustomWidget('test', 4)),
                    Expanded(child: CustomWidget('test', 5)),
                ],
            ),
        ),
        Padding(
            padding: const EdgeInsets.only(right: 8, top: 8),
            child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                    Expanded(child: CustomWidget('test', 6)),
                    Expanded(child: CustomWidget('test', 7)),
                    Expanded(child: CustomWidget('test', 8)),
                ],
            ),
        ),
        Padding(
            padding: const EdgeInsets.only(right: 8, top: 8),
            child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                    Expanded(child: CustomWidget('test', 9)),
                    Expanded(child: CustomWidget('test', 10)),
                    Expanded(child: CustomWidget('test', 11)),
                ],
            ),
        ),
    ],
),
  

Ответ №1:

Вы можете использовать ListView.builder .

 ListView.builder(
        itemCount: 10,
        itemBuilder: (context, index) =>
            Padding(
              padding: const EdgeInsets.only(right: 8, top: 8),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Expanded(child: _customWidget('test')),
                  Expanded(child: _customWidget('test')),
                  Expanded(child: _customWidget('test')),
                ],
              ),
            ),
      ),
  

И если у вас есть dynamic List<model> , вы можете установить длину списка itemCount в ListView дюймах.

Обновить

полный код с «поддельным простым элементом списка».

 import 'package:flutter/material.dart';

class Training extends StatefulWidget {
  @override
  _TrainingState createState() => _TrainingState();
}

class _TrainingState extends State<Training> {
  Map<int, List<String>> mMap;

  void _initMap() {
    mMap = Map();
    for (int i = 0; i < 100; i  ) {
      List<String> subtitleList = List();
      for (int j = 0; j < 3; j  ) {
        subtitleList.add("Sub $j of Title $i");
      }
      mMap[i] = subtitleList;
    }
  }

  @override
  void initState() {
    super.initState();
    _initMap();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:
      ListView.builder(
        itemCount: mMap.length,
        itemBuilder: (context, index) =>
            Padding(
              padding: const EdgeInsets.only(right: 8, top: 8),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: _getChildren(mMap[index]),
              ),
            ),
      ),
    );
  }

  List<Widget> _getChildren(List<String> list) {
    List<Widget> output = List();
    list.forEach((element) {
      output.add(_customWidget(element));
    });
    return output;
  }

  Widget _customWidget(String s) {
    return Expanded(child: Container(margin: EdgeInsets.all(8), child: Text(s)));
  }
}

  

Комментарии:

1. Спасибо. Но если я это сделаю, я думаю, будут проблемы с индексом. Мне нужно передать индекс для каждого виджета. В итоге будет повторяться 3 одинаковых виджета в строке.

2. Я обновил свой пост по вашему запросу. конечно, коды зависят от типа имеющихся у вас данных

Ответ №2:

Вы можете использовать GridView с List.generate . Установите myLength значение для виджетов, которые он должен генерировать. Используйте [index] внутри каждого виджета для получения определенных данных из массива. пример: если у вас есть массив myProducts , установите длину в my myProducts.length , а затем используйте внутри myProducts[index]

 GridView.count(
   mainAxisSpacing: 6,
   crossAxisCount: 1,
   childAspectRatio: (200 / 67), // (width/height)
   children: List.generate(
      myLength, (index) {
         return Padding(
            padding: const EdgeInsets.only(right: 8, top: 8),
            child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                    Expanded(child: CustomWidget('test)),
                    Expanded(child: CustomWidget('test)),
                    Expanded(child: CustomWidget('test)),
                ],
            ),
        );
      }
   ),
),
  

Комментарии:

1. Есть ли способ, которым я мог бы изменить это, чтобы получить правильные значения индекса? Потому что первое значение индекса равно 0, и я планирую отправить это значение в CustomWidget. Для первого цикла я должен получить индекс 0, 1, 2 вместо 0, 0, 0. Следующий цикл 3,4,5 и так далее. Одна из возможностей — написать некоторый логический метод, который принимает индексы и выполняет вычисления и выводит новое значение индекса для использования. Пытаюсь избежать этого.

2. [индекс 1] или применить логику к индексу с помощью функции