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

#android #flutter #sorting #dart

Вопрос:

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

Я могу отсортировать список при загрузке страницы, но я не могу изменить порядок сортировки, используя раскрывающиеся параметры.

Код соответствует требованиям без ошибок.

Есть какие-нибудь советы, что мне нужно изменить, чтобы этот код работал?

 class NewList extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _State();
}

class _State extends State<NewList> {
  static dates;
  List<Entry> _entryList = [];
  List<Entry> _sort = [];
  StreamController<int> _postsController;
  
  List<Option> options = [];
  Option _selectedOption;

  void _select(Option option) {
    setState(() {
      _selectedOption = option;
    });

    if (_selectedOption.title =='Oldest first') {
            _sort.sort((a, b) {
                return b.id.compareTo(a.id);
            });
    } else if (_selectedOption.title =='Newest first') {
            _sort.sort((a, b) {
                return a.id.compareTo(b.id);
            });
    } 
  }

  @override
  void initState() {
    _postsController = new StreamController();
    fetchReport();
    super.initState();
  }

  fetchReport() {
     fecthEntries(dates.id.toString(), dates.from, dates.to)
         .then((value) => {
              _entryList.addAll(value),
              _postsController.add(1),
              setState(() {})
           });        
  }

  @override
  Widget build(BuildContext context) {
    dates = ModalRoute.of(context).settings.arguments;
    
    options = <Option>[
      Option(
          title: 'Oldest first',
      Option(
          title: 'Newest first',
    ];
    _selectedOption = options[0];

    return Scaffold(
      appBar: AppBar(
        title: Text('Title'),
        actions: <Widget>[
          PopupMenuButton<Option>(
            onSelected: _select,
            icon: Icon(Icons.sort),
            itemBuilder: (BuildContext context) {
              return options.map((Option option) {
                return PopupMenuItem<Option>(
                  value: option,
                  child: Text(option.title),
                );
              }).toList();
            },
          ),
        ],
      ),
      body: StreamBuilder<int>(
          stream: _postsController.stream,
          builder: (BuildContext context, AsyncSnapshot<int> result) {
            if (result.hasData) {
              return showAll();
            } 
          }),
    );
  }

  Widget showAll() {
    //This is where I can sort the list onload and setup the default sort
    _entryList.sort((a, b) {
        return b.id.compareTo(a.id);
    });
    return ListView.builder(
      itemCount: _entryList.length,
      itemBuilder: (context, index) {
        final entry = _entryList[index];
        return reportRow(entry, context);
      },
    );
  }

}

class Option {
  const Option({this.title});
  final String title;
}
 

Ответ №1:

Я бы также попытался обернуть логику сортировки с помощью setState (). Вы пробовали?

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

1. Что-то вроде этого? — setState(() { _sort.sort((a, b) { return b.id.compareTo(a.id); }); }); К сожалению, это не работает…

2. Внутри вашего метода _select у вас уже есть setState(){}. Оберните все содержимое метода внутри этого метода setState.

3. еще одна догадка… внутри метода сборки вы всегда устанавливаете: _selectedOption = параметры[0]; При этом значение раскрывающегося списка не может измениться. Переместите объявление за пределы метода сборки.

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