Flutter Firebase просмотр списка с фильтрами

#flutter #listview #google-cloud-firestore #dropdown

#flutter #listview #google-облако-firestore #выпадающий список

Вопрос:

Я создал listview в flutter, который извлекает данные из firestore. Пока это работает нормально, но теперь я хочу добавить несколько фильтров, используя выпадающий список, который будет фильтровать listview на основе значений выпадающего списка, выбранных пользователем. Итак, прямо сейчас, когда приложение загружается в первый раз, listview отображается правильно, но когда я меняю значения в выпадающем списке, список не меняется. Я хочу обновить listview, когда пользователь выбирает выпадающее значение.

введите описание изображения здесь

Это панель приложений, где у меня есть два фильтра (выпадающие значения). И когда пользователь захочет изменить значения фильтра (из выпадающего списка), список должен обновляться.

 import 'package:cloud_firestore/cloud_firestore.dart';

class LandingPage extends StatefulWidget {
  @override
  _LandingPageState createState() => _LandingPageState();
}
 String _currentlySelectedage = "2"; 
 String _currentlySelectedlanguage = "english";

  class _LandingPageState extends State<LandingPage> {
  final List<String> _dropdownValuesage = ["1","2","3"]; 
  final List<String> _dropdownValueslanguage = ["silent", "english","hindi"];
 

  Widget dropdownWidgetage() {
    return DropdownButton(
      isExpanded: false,
      value:_currentlySelectedage,
      onChanged: (String newvalue) {
        setState(() {
          _currentlySelectedage = newvalue;
          print(_currentlySelectedage);
        });
      },
      items: _dropdownValuesage
          .map((value) => DropdownMenuItem(
                child: Text(value),
                value: value,
              ))
          .toList(),
    );
  }

  Widget dropdownWidgetlanguage() {
    return DropdownButton(
      isExpanded: false,
      value:_currentlySelectedlanguage,
      onChanged: (String newvalue) {
        setState(() {
          _currentlySelectedlanguage = newvalue;
          print(_currentlySelectedlanguage);
        });
      },
      items: _dropdownValueslanguage
          .map((value) => DropdownMenuItem(
                child: Text(value),
                value: value,
              ))
          .toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        centerTitle: false,
        title: Text('',style: TextStyle(fontFamily: 'Raleway'),),
        backgroundColor: Colors.teal,
        actions: <Widget>[
          dropdownWidgetage(),
          SizedBox(width:4),
          dropdownWidgetlanguage()
        ],
      ),
      body: ListPage(),
    );
  }
}

class ListPage extends StatefulWidget {
  @override
  _ListPageState createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
  Future _data;

  Future getPosts() async {
    var firestore = Firestore.instance;
    QuerySnapshot qn = await firestore
        .collection("movies")
        .where("age", arrayContains: _currentlySelectedage)
        .where("language", isEqualTo: _currentlySelectedlanguage)
        .orderBy('rank', descending: true)
        .getDocuments();
    return qn.documents;
  }

  navigateToDetail(DocumentSnapshot post) {
    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => DetailPage(
                  post: post,
                )));
  }

  @override
  void initState() {
    super.initState();
    _data = getPosts();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder(
          future: _data,
          builder: (_, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: Text("Loading...."),
              );
            } else {
              return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (_, index) {
                    return Card(
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            children: [
                          InkWell(
                            onTap: () => navigateToDetail(snapshot.data[index]),
                            child: Image.network(
                                snapshot.data[index].data['gff']),
                          ),
                          Text(
                            snapshot.data[index].data['gfg'],
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 20),
                          ),
                        ]));
                  });
            }
          }),
    );
  }
}
  

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

1. Проблема в том, что выполнение запроса происходит только один раз, и это тоже в начале, когда запускается приложение. Я просто хочу, чтобы запрос выполнялся снова, когда пользователь изменяет значения выпадающего списка и нажимает «Перейти» (кнопка, которую я буду реализовывать).

Ответ №1:

Flutter кэширует виджеты, чтобы избежать ненужных перестроек. Когда он переходит к сборке ListPage() во второй раз, он видит, что параметры не изменились, потому что параметров нет, и повторно использует кэшированную версию из первой сборки. Преобразуйте глобальные переменные в параметры, и все должно быть в порядке.