flutter: виджеты перестраиваются, даже если используется `provider` - PullRequest
0 голосов
/ 02 марта 2020

Я использую provider для управления состоянием флаттера. Ниже мой код

Дом

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          //backgroundColor: Color.fromRGBO(0, 72, 100, 10),
          backgroundColor: Color.fromRGBO(25, 72, 114, 10),
          title: Text("something"),
          bottom: TabBar(
            indicatorColor: Colors.white70,
            labelStyle: TextStyle(
                fontFamily: 'Roboto-Regular',
                fontSize: 16.0,
                letterSpacing: 0.15),
            labelColor: Colors.white,
            labelPadding: EdgeInsets.all(5),
            tabs: <Widget>[
              Tab(
                text: "Fresh Products",
              ),
              Tab(
                text: "Frozen Products",
              ),
            ],
          ),
        ),
        body: Center(child: Home()),
      ),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("Home build methof");
    return TabBarView(
      children: <Widget>[
        Container(
          height: double.infinity,
          child: FutureBuilder(
            future: Provider.of<ProductSpeciesImpl>(context, listen: false)
                .getAllSpecies(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return Center(
                  child: Container(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        CircularProgressIndicator(),
                        Container(
                          height: 10,
                        ),
                        Text(
                          "Loading Data... Please Wait",
                          style: Theme.of(context).textTheme.body1,
                        )
                      ],
                    ),
                  ),
                );
              } else {
                if (snapshot.hasError) {
                  return Center(
                    child: Text("An error Occured"),
                  );
                } else {
                  return Consumer<ProductSpeciesImpl>(
                      builder: (context, data, child) => GridView.builder(
                          physics:
                              ScrollPhysics(), // to disable GridView's scrolling
                          shrinkWrap: true,
                          itemCount: Provider.of<ProductSpeciesImpl>(context)
                              .productList
                              .length,
                          gridDelegate:
                              new SliverGridDelegateWithFixedCrossAxisCount(
                                  childAspectRatio:
                                      (MediaQuery.of(context).size.width *
                                          .5 /
                                          190),
                                  crossAxisCount: 2),
                          itemBuilder: (BuildContext context, int index) {
                            return GestureDetector(
                              onTap: () {
                                //print("sdsdsdsd");
                                // print(snapshot.data[index].name + " " + snapshot.data[index].idProductSpecies.toString() + " "+ snapshot.data[index].photo);
                                Navigator.pushNamed(context, "/products",
                                    arguments: {
                                      "name": Provider.of<ProductSpeciesImpl>(
                                              context,
                                              listen: false)
                                          .productList[index]
                                          .name,
                                      "id": Provider.of<ProductSpeciesImpl>(
                                              context,
                                              listen: false)
                                          .productList[index]
                                          .idProductSpecies,
                                      "photo": Provider.of<ProductSpeciesImpl>(
                                              context,
                                              listen: false)
                                          .productList[index]
                                          .photo
                                    });
                              },
                              child: Card(
                                elevation: 4.0,
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(8.0)),
                                clipBehavior: Clip.antiAlias,
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  children: <Widget>[
                                    Container(
                                      child: Text(
                                        Provider.of<ProductSpeciesImpl>(context,
                                                listen: false)
                                            .productList[index]
                                            .name,
                                      ),
                                    )
                                  ],
                                ),
                              ),
                            );
                          }));
                }
              }
            },
          ),
        ),

ProductSpeciesImpl

class ProductSpeciesImpl
    with ChangeNotifier
    implements ProductSpeciesInterface {
  NavLinks navLinks = NavLinks();

  List<ProductSpecies> productList = [];

  @override
  Future<void> getAllSpecies() async {
    var data = await http.get(navLinks.getAllProductSpecies());
    var jsonData = convert.json.decode(data.body).cast<Map<String, dynamic>>();

    try {
      productList = jsonData
          .map<ProductSpecies>((json) => new ProductSpecies.fromJson(json))
          .toList();

      print("Product sIZE: " + productList.length.toString());

      notifyListeners();
    } catch (error) {
      throw error;
    }
  }
}

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

Благодарим вас за поддержку, чтобы решить эту проблему.

1 Ответ

1 голос
/ 02 марта 2020

Вы инициируете HTTP-запрос в вашей функции build(), вызывая getAllSpecies(). Вы не должны этого делать. Функции

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //...
          child: FutureBuilder(
            future: Provider.of<ProductSpeciesImpl>(context, listen: false)
                .getAllSpecies(),

build() не должны иметь побочных эффектов. Пожалуйста, преобразуйте виджет в StatefulWidget и загрузите в initState(). В качестве альтернативы, заставьте родителя StatefulWidget выполнить загрузку в его initState() и передать данные этому виджету в его конструкторе.

...