Создание и сортировка нового списка на основе предоставленного списка и параметров

У меня есть список моделей:

class Model {
final DateTime date;
final String text;

Model({this.date, this.text});
}

List<Model> _models = [
Model(date: DateTime(2018, 9, 1), text: 'Text1',),
Model(date: DateTime(2018, 9, 1), text: 'Text2',),
Model(date: DateTime(2018, 9, 2), text: 'Text3',),
Model(date: DateTime(2018, 9, 3), text: 'Text4',),
Model(date: DateTime(2018, 8, 31), text: 'Text7',),
Model(date: DateTime(2018, 9, 3), text: 'Text5',),
Model(date: DateTime(2018, 9, 3), text: 'Text6',),
];

Я пытаюсь взять параметр даты из каждой модели и поместить все модели, соответствующие этой дате, в ListView (). Так что я могу вернуть список моделей на каждую дату. Каждый раз, когда я добавляю данные в список, я хочу, чтобы они обновлялись и сортировались по дате автоматически (без ручного труда). Форматирование даты здесь не важно. Вопрос: как я могу этого добиться?

Вот как я хочу, чтобы он выглядел:
2018/9/3
Text4
Текст5
Text6

2018/9/2
Text3

2018/9/1
Текст1
Text2

31.08.2018
Text7

3
0
2 995
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Для простого решения с использованием существующего виджета; вы можете использовать side_header_list_view (https://pub.dartlang.org/packages/side_header_list_view)

пример :

Widget _buildList(){ 

 return new SideHeaderListView(
      itemCount: _models.length,
      itemExtend: 100.0,
      headerBuilder: (BuildContext context, int index) {
        return Text(_models[index].date);
      },
      itemBuilder: (BuildContext context, int index) {
        return new Card(
          child: Text(_models[index].text),
        );
      },
      hasSameHeader: (int a, int b) {
        return _models[a].date == _models[b].date;
      },
    );

}

Не тестировал, в идеале должен работать, при условии, что вам может потребоваться некоторое форматирование даты в строковый тип, прежде чем передавать ее в текст .. Считайте это пока псевдокодом.

Я старался избегать использования сторонних пакетов;) К тому же фиксированная высота - это не то, что я ищу. Но все равно спасибо.

user8239476 10.09.2018 22:15
Ответ принят как подходящий

Для другого простого примера без сторонних пакетов:

import 'package:flutter/material.dart';

class Model {
  final DateTime date;
  final String text;

  Model({this.date, this.text});
}

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sample App',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // Populate initial value for the list of models
  List<Model> _models = [
    Model(
      date: DateTime(2018, 9, 1),
      text: 'Text1',
    ),
    Model(
      date: DateTime(2018, 9, 1),
      text: 'Text2',
    ),
    Model(
      date: DateTime(2018, 9, 2),
      text: 'Text3',
    ),
    Model(
      date: DateTime(2018, 9, 3),
      text: 'Text4',
    ),
    Model(
      date: DateTime(2018, 8, 31),
      text: 'Text7',
    ),
    Model(
      date: DateTime(2018, 9, 3),
      text: 'Text5',
    ),
    Model(
      date: DateTime(2018, 9, 3),
      text: 'Text6',
    )
  ];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.plus_one),
        onPressed: () {
          setState(() {

            // On click of floating action button, add a hardcoded item to _models list
            _models.add(Model(
              date: DateTime(2018, 9, 2),
              text: 'New Item',
            ));
          });
        },
      ),
      body: SortedGroupedList(_models),
    );
  }
}

class SortedGroupedList extends StatefulWidget {
  final List<Model> list;
  SortedGroupedList(this.list);

  @override
  State<StatefulWidget> createState() => _SortedGroupedListState();
}

class _SortedGroupedListState extends State<SortedGroupedList> {
  List<Model> _list;
  @override
  void initState() {
    super.initState();
    _list = widget.list;
  }

  @override
  Widget build(BuildContext context) {
    _list.sort((a, b) => b.date.compareTo(a.date));
    Model prev;
    bool shownHeader = false;

    List<Widget> _listChildren = <Widget>[];
    _list.forEach((Model model) {
      if (prev != null && model.date != prev.date) {
        shownHeader = false; // if dates are different, beginning of a new group, so header is yet to be shown
      }

      if (!shownHeader) {
        // if header for a group is not shown yet, add it to the list
        _listChildren.add(ListTile(
            title: Text(
          model.date.toString(),
          style: TextStyle(fontWeight: FontWeight.bold),
        )));
        prev = model; // keep the current model for reference to check if group has changed
        shownHeader = true;
      }

      _listChildren.add(ListTile(title: Text(model.text)));
    });

    return ListView(children: _listChildren);
  }
}

В этом примере мы создаем новый виджет с именем SortedGroupedList, который будет принимать список моделей и сортировать его в порядке убывания, а затем отображать его с помощью ListView, отслеживая элементы, сгруппированные по их датам.

Также onPress из FloatingActionButton добавит еще один жестко запрограммированный элемент в список при нажатии кнопки с плавающим действием, и это отражается с помощью 'no manual stuff' (что бы это ни было;)). Этот пример можно улучшить, чтобы управлять списком _model, и в идеале все изменения должны отражаться в нашем представлении.

Обратите внимание, что этот пример может быть не идеальным для огромного списка, так как список необходимо сортировать каждый раз, когда в него вносятся какие-либо изменения. Лучшим подходом может быть использование ListView.builder (), но это может быть сложным в зависимости от операций, которые вы хотите выполнить со списком.

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