簡體   English   中英

flutter:即使使用了`provider`,小部件也在重建

[英]flutter: Widgets are rebuilding even though `provider` is used

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

產品種類Impl

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 都會重新加載。 我用過consumer ,據我所知, consumer只會在調用時加載相關部分。 這意味着我也不必在init運行我的產品加載代碼。 所以,我不明白為什么會這樣。

感謝您對解決此問題的支持。

您在此處通過調用getAllSpecies()build()函數中發起 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()加載並在其構造函數中將數據傳遞給此小部件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM