Как изменить StreamProvider при изменении дочернего значения во флаттере с помощью firestore? - PullRequest
0 голосов
/ 14 июля 2020

Я сталкиваюсь с проблемой состояния при использовании провайдеров StreamProvider, использующих базу данных firestore. Приложение получает объекты и отображает их в списке над ListView.builder. Теперь я хочу, чтобы пользователь изменил настройки, чтобы он / она мог фильтровать результаты по своим предпочтениям. Поскольку я новичок в флаттере и разработке приложений в целом, я не знаю, как заставить это работать. Вот основной код:

return StreamProvider<List<Cocktails>>.value(
        value: CocktailsDatabase().cocktails,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.black,
          title: isSearching? TextFormField(
            onChanged: (value){
            setState(() {
              searchQuery = value;
            });
            },
            style: TextStyle(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 18.0),
            decoration: InputDecoration(
              border: InputBorder.none,
              hintText: 'Zoek naar cocktails...',
              hintStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.w200),
              contentPadding: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
              fillColor: Colors.white,
              icon: IconButton(
                onPressed: (){
                  setState(() {
                    isSearching = false;
                  });
                },
                icon: Icon(Icons.close, color: Colors.white),

              )
            ),

          ): Center(
              child: Image.asset('assets/images/logo_white_large_textonly.png',
                fit: BoxFit.contain,
                height: 50,
                width: 120,
              )),
          actions: <Widget>[
            FlatButton.icon(
            onPressed: (){
              if (isSearching == false){
                setState(() {
                  isSearching = true;
                });
              } else{
                setState(() {
                  isSearching = false;
                });
              }
            },
            icon: isSearching? Icon(Icons.arrow_forward, color: Colors.white) : Icon(Icons.search,color: Colors.white),
            label: Text('')),
          ],
        ),
        body: CocktailList(),
        floatingActionButton: FloatingActionButton(
          onPressed: _showFiltersPanel,
          child: Icon(Icons.tune),
          backgroundColor: Colors.red,
        ),
          )
      );
  }

  void _showFiltersPanel(){
    showModalBottomSheet(context: context,
        elevation: 20.0,
        builder: (context){
          return Container(
            padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
            child: FilterForm(),
          );
        });
  }

Где CocktailList () - это отдельный виджет для построения списка объектов, а _shoFiltersPanel - это отдельная встроенная функция для рисования нижнего листа на экране для изменения настроек поиска.

Код CocktailList ():

class CocktailList extends StatefulWidget {
  @override
  _CocktailListState createState() => _CocktailListState();
}

class _CocktailListState extends State<CocktailList> {
  @override
  Widget build(BuildContext context) {

    final List<String> orderList = ['A-Z', 'Z-A', 'Meest favoriet'];

    double searchTime;
    double searchDifficulty;
    double searchStrength;
    String order;
    bool alcoholic = true;
    Cocktails cocktail;

    List cocktails = Provider.of<List<Cocktails>>(context);

    List filteredCocktails = [];
    


    return ListView.builder(
      itemCount: cocktails.length,
      itemBuilder: (context, index){
        return CocktailCard(cocktail: cocktails[index]);
      },
    );


  }
}

где неиспользуемые переменные используются для изменения настроек того, при каких условиях строить список. Эти переменные можно изменить в de FilterForm () с помощью кода:


class _FilterFormState extends State<FilterForm> {

  final List<String> orderList = ['A-Z', 'Z-A', 'Meest favoriet'];

  double searchTime;
  double searchDifficulty;
  double searchStrength;
  String order;
  bool alcoholic = true;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        Column(
          mainAxisSize: MainAxisSize.min,
         children: <Widget>[
           Text('Bereidingstijd'),
           Slider(
             value: (searchTime ?? 1.0),
             min: 1.0,
             max: 10.0,
             divisions: 9,
             onChanged: (val) => setState(() => searchTime = val),
             activeColor: Colors.red,
             inactiveColor: Colors.redAccent,
             label: searchTime.toString(),
           ),
           Text('Moeilijkheid'),
           Slider(
             value: (searchDifficulty ?? 1.0),
             min: 1.0,
             max: 5.0,
             divisions: 4,
             onChanged: (val) => setState(() => searchDifficulty = val),
             activeColor: Colors.red,
             inactiveColor: Colors.redAccent,
             label: searchDifficulty.toString(),
           ),
           Text('Sterkte'),
           Slider(
             value: (searchStrength ?? 1.0),
             min: 1.0,
             max: 10.0,
             divisions: 9,
             onChanged: (val) => setState(() => searchStrength = val),
             activeColor: Colors.red,
             inactiveColor: Colors.redAccent,
             label: searchStrength.toString(),
           ),
         ],
        ),
        Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            DropdownButton(
              value: order ?? 'A-Z',
              onChanged: (newOrder){
                setState(() {
                  order = newOrder;
                });
              },
              icon: Icon(Icons.sort),
              items: orderList.map((order){
                return DropdownMenuItem(
                  value: order,
                  child: Text('$order'),
                );
              }).toList()
            ),
            Text('Alcoholisch'),
            Switch(
              value: alcoholic,
              activeColor: Colors.red,
              onChanged: (bool state){
                setState(() {
                  alcoholic = state;
                });
              },
            ),
              SizedBox(
                height: 50.0,
                width: 150.0,
                child: Align(
                  alignment: Alignment.bottomRight,
                  child: FloatingActionButton(
                    onPressed: (){},
                    child: Icon(Icons.search),
                    backgroundColor: Colors.red,
                  ),
                ),
              ),

          ],
        )
      ],
    );
  }
}

Помощь будет потрясающей!

...