Проверить / снять флажок ListTiles в ListView.builder () - Flutter - PullRequest
0 голосов
/ 15 октября 2018

У меня есть ListView.builder(); в showModalBottomSheet(); Нужно выбрать / отменить выбор нескольких элементов на кране, все хорошо, но нужно закрыть модал и показать его снова, чтобы применить изменения, другая вещь - это ListTiles, иногда дублируемая более чемоднажды функция emptyList не работает хорошо.

    import 'package:http/http.dart' as http;
    import 'dart:convert';
    import 'dart:async';
    import 'package:flutter/material.dart';
    import 'book_details.dart' show BookDetails;

    class Explore extends StatefulWidget {
      @override
      _ExploreState createState() => _ExploreState();
    }

    var _books,
        _categories,
        _arranges,
        _currentCategory,
        _selected,
        _primeColor,
        _currentFilter,
        _isThereIsFilters,
        _booksContainer,
        _booksWithFilters,
        _isLoading,
        _noBooks,
        _itemIcon;

    final GlobalKey<ScaffoldState> _scaffoldKeyExplore =
        new GlobalKey<ScaffoldState>();

    List<String> _getCats = new List();
    List<String> _getArrs = new List();

    void _insertCategories() {
      for (int i = 0; i < _categories.length; i++) {
        _getCats.add(_categories[i]);
      }
      _getCats.sort();
    }

    void _insertArranges() {
      for (int i = 0; i < _arranges.length; i++) {
        _getArrs.add(_arranges[i]);
      }
    }

    class _ExploreState extends State<Explore> with TickerProviderStateMixin {

      onCatChange(String category) {
        setState(() {
          _currentCategory = category;
        });
      }

      @override
      void initState() {
        super.initState();
        _primeColor = Color.fromRGBO(239, 89, 39, 1.0);
        _categories = ["أول", "ثاني", "ثالث", "رابع", "خامس"];
        _arranges = ["أول", "ثاني", "ثالث", "رابع", "خامس"];
        _currentFilter = _arranges[0];
        _selected = [];
        _isThereIsFilters = false;
      }

      void emptyList(List list) {
        for (var i = 0; i < list.length; i++) {
          list.remove(list[i]);
        }
      }

      _showSheet(String type) {
        switch (type) {
          case "filters":
            showModalBottomSheet(
                context: _scaffoldKeyExplore.currentContext,
                builder: (BuildContext context) {
                  return Directionality(
                    textDirection: TextDirection.rtl,
                    child: Container(
                        child: Column(children: <Widget>[
                      Expanded(
                        child: new ListView.builder(
                            itemCount: _getArrs[0] != null ? _getArrs.length : 0,
                            itemBuilder: (BuildContext context, int i) {
                              return new RadioListTile(
                                  title: Text(_getArrs[i]),
                                  value: _getArrs[i],
                                  groupValue: _currentFilter,
                                  onChanged: (val) {
                                    setState(() {
                                      _currentFilter = val;
                                    });
                                  });
                            }),
                      )
                    ])),
                  );
                });
            break;

          case "categories":
          default:
            showModalBottomSheet(
                context: _scaffoldKeyExplore.currentContext,
                builder: (BuildContext context) {
                  return Directionality(
                    textDirection: TextDirection.rtl,
                    child: Container(
                        child: Column(children: <Widget>[
                          Container(
                            color: _primeColor,
                            child: Row(
                                mainAxisSize: MainAxisSize.max,
                                mainAxisAlignment: MainAxisAlignment.end,
                                children: <Widget>[
                                  IconButton(
                                      icon: Icon(Icons.close, color: Colors.white),
                                      onPressed: () {
                                        emptyList(_selected);
                                        //Navigator.pop(context);
                                        //_showSheet(type);
                                      }),
                                  IconButton(
                                      icon:
                                          Icon(Icons.done_all, color: Colors.white),
                                      onPressed: () {
                                        if (_selected.length > 0) {
                                          _getFilteredBooks(_selected);
                                          setState(() {
                                            _isThereIsFilters = true;
                                          });
                                        } else {
                                          setState(() {
                                            _isThereIsFilters = false;
                                          });
                                        }
                                        Navigator.pop(context);
                                      })
                                ]),
                          ),
                          Expanded(
                            child: new ListView.builder(
                                itemCount: _getCats != null ? _getCats.length : 0,
                                itemBuilder: (BuildContext context, int i) {
                                  final _isSelected = _selected.contains(_getCats[i]);
                                  return new ListTile(
                                      leading: Icon(Icons.category),
                                      trailing: _isSelected ? Icon(Icons.done) : null,
                                      title: Text(_getCats[i]),
                                      onTap: () {
                                        setState(() {
                                          _isSelected
                                              ? _selected.remove(_getCats[i])
                                              : _selected.add(_getCats[i]);
                                        });
                                        //Navigator.pop(context);
                                        //_showSheet(type);
                                      });
                                }),
                          )
                        ])),
                  );
                });
            break;
        }
      }

      @override
      Widget build(BuildContext context) {
        return new Directionality(
            textDirection: TextDirection.rtl,
            child: new Scaffold(
              key: _scaffoldKeyExplore,
              appBar:
                  AppBar(title: Text("استكشاف"), elevation: 0.0, actions: <Widget>[
                IconButton(
                    icon: Icon(Icons.category, color: _primeColor),
                    onPressed: () => _showSheet("categories")),
                IconButton(
                    icon: Icon(Icons.filter_list, color: _primeColor),
                    onPressed: () => _showSheet("filters"))
              ]),
              body: Center(child: Text("Nothing..."));
            ));
      }
    }

Спасибо

1 Ответ

0 голосов
/ 15 октября 2018

необходимо закрыть модальное окно и показать его снова, чтобы применить изменения

Это происходит потому, что showModalBottomSheet builder необходимо вызвать снова, чтобы отразить изменения.Во Flutter StatefulWidget s может быть в состоянии восстановить в любое время при изменении состояния, что здесь не так из-за показа нижнего листа.

Почему я столкнулся с этой проблемой (на уровне мета)?

Сохранение состояния в StatefulWidget s полезно для сохранения состояния пользовательского интерфейса, но вы быстро перерастете эту технику, если хотите сохранить какое-то «состояние приложения» или «состояние данных».", который не зависит от того, на каком экране он находится.

Настало время фундаментально переосмыслить ваше управление состоянием и установить полноценный шаблон управления состоянием, который отделяет состояние от виджетов.К счастью, есть несколько вариантов:

  • Создание всего глобального , как вы делали выше. Как правило, это не очень хорошая идея , поскольку вы нарушаете контракт на setState (состояние может быть изменено без уведомления виджетов).Кроме того, вы прерываете горячий перезапуск и все в таком духе.
  • Используя InheritedWidget, где виджеты ниже корневого виджета могут получить доступ к тому же состоянию.
  • Использование ScopedModel, который строится поверх этого.
  • Использование печально известного BLoC паттерна , который также строится поверх InheritedWidget, но добавляет немного Stream -й материал, чтобы сделать все более реактивным.
  • Вероятно, намного больше.

Вот отличное Youtube видео об управлении состоянием из Google I / O ,где представлены несколько шаблонов.

В любом случае, являются ли нижние листы правильным виджетом для предстоящей задачи?

Согласно Спецификации дизайна материала нижний модальный лист - это «альтернатива встроенным меню или простым диалоговым окнам на мобильном телефоне, обеспечивающая место для дополнительных элементов, более длинных описаний и иконографии».

Более конкретно, функция showModalBottomSheet предназначена для показавиджет, который не влияет на родителя с течением времени, а скорее- если вообще - в один момент времени.Вот почему он возвращает Future<T>, а не Stream<T>.

Имейте в виду, что вы пытаетесь использовать нижний лист так, как он не предназначен для использования.В вашем случае я бы порекомендовал просто использовать новый экран.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...