颤抖:即使使用了“ provider”,小部件仍在重建

时间:2020-03-02 10:50:11

标签: android ios flutter flutter-layout flutter-provider

我正在使用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;
    }
  }
}

代码工作正常。问题是每次我访问另一个页面并返回此页面时,UI都会重新加载。据我了解,我使用过consumerconsumer仅在相关部分被调用时加载。这意味着我也不必在init内部运行产品加载代码。所以,我不明白为什么会这样。

感谢您的支持以解决此问题。

1 个答案:

答案 0 :(得分:1)

您正在通过调用build()getAllSpecies()函数中发起HTTP请求。您不应该这样做。

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

build()函数应该没有副作用。请将该小部件转换为StatefulWidget,然后在initState()中进行加载。或者,让父项StatefulWidget在其initState()中进行加载,然后将数据交给其构造函数中的此窗口小部件。