【问题标题】:Flutter - setState not updating Widgets?Flutter - setState 不更新小部件?
【发布时间】:2020-08-18 14:24:33
【问题描述】:

我正在尝试为我的应用构建评论部分。在那方面,我试图拥有一个阅读更多功能,显然顾名思义,它会在点击小部件时扩展小部件以显示更多文本。 我正在使用带有 BottomNavigationBar 的索引堆栈在评论和产品页面之间切换。

import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'Product_Page_Widgets.dart';
void main() => runApp(Product());
class Product extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ProductState(),
    );
  }
}
class ProductState extends StatefulWidget {
  Map<dynamic,dynamic> productData;
  CollectionReference reviews;
  ProductState({@required this.productData,@required this.reviews});
  @override
  _ProductStateState createState() => _ProductStateState();
}

class _ProductStateState extends State<ProductState>  with TickerProviderStateMixin{
  List<NetworkImage> _Images = [];
  List<Widget> productImages = [];
  List<Widget> reviewWidgets = [];
  String changeableText = "";
  List<String> firstHalf = [];
  List<String> secondHalf = [];
  var cardHeight = [];

  bool load  = false;

  int pageIndex = 0;

  List<Widget> pageWidget = [];
  addPageWidgets() async{
    pageWidget.add( ProductPageWidget(
        productName: widget.productData['Name'],
        galleryItems: _Images,cachedImages: productImages,description:widget.productData['description'] ?? "placeholder")

    );
    Widget w =  await buildReviewsWidgets();
    pageWidget.add(w);

  }
  GlobalKey key = new GlobalKey();
 Future <Widget> buildReviewsWidgets() async{

    var docs = await widget.reviews.getDocuments();
    var documents = docs.documents;

      print(documents.toString());
    if(docs != null) {

      for (int i = 0; i < documents.length; i++) {
        cardHeight.add(MediaQuery.of(context).size.height/4);
        print(documents[i].data['Review']);
       if(documents[i].data['Review'].toString().length>50){
         firstHalf.add( documents[i].data['Review'].toString().substring(0,50));
         secondHalf.add(documents[i].data['Review'].toString().substring(51));

       }else{
         firstHalf.add( documents[i].data['Review'].toString());
          secondHalf.add("");

       }


      }



    }
    for(var doc in documents){
      print(doc.data);

    }


  return Container(
        height:MediaQuery.of(context).size.height,
        child: ListView.builder(
          key: key,
          itemCount: documents.length,
          itemBuilder: (context,index) => AnimatedSize(
            vsync: this,
            curve: Curves.easeIn,
            duration: new Duration(milliseconds: 300),
            child: Container(
              height: cardHeight[index],
              child: Card(

                elevation: 2.0,

                child: ListTile(
                  onTap: (){
                    stateUpdate(index);
                  },
                    leading: CircleAvatar(),
                    title: Text(documents[index].data['Title']),

                    subtitle: Column(children: [

                      RatingBar(
                        itemBuilder: (context, _) => Icon(
                          Icons.star,
                          color: Colors.amber,
                        ),
                        maxRating: 5.0,
                        allowHalfRating: false,
                        ignoreGestures: true,
                        initialRating: int.parse(documents[index].data['Rating'].toString()).toDouble(),
                      ),
                      Wrap(
                        children: <Widget>[
                          Text(firstHalf[index].toString()),
                          Text("Read More")
                        ],
                      ),
                    ]),
                  ),

              ),
            ),
          ),
        ),
      );

}
void AddNetworkImages (BuildContext context){
  if(!load) {

    for (int i = 0; i < widget.productData.length; i++) {
      if (widget.productData.containsKey('Img$i')) {
        print("Img$i exists");
        _Images.add(
            NetworkImage(widget.productData['Img$i'])
        );
        productImages.add(
          CachedNetworkImage(
            imageUrl: widget.productData['Img$i'],
            placeholder: (context, url) => CircularProgressIndicator(),
            errorWidget: (context, url, error) => Icon(Icons.error),

          ),
        );
      }
    }
  }
}
void loadWidgets(BuildContext context){
  setState(() {

  });
  load = true;

}
  @override
  void initState() {
    //AddNetworkImages(context);
    addPageWidgets();

    super.initState();



  }

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance
        .addPostFrameCallback((_) => AddNetworkImages(context));

    WidgetsBinding.instance
        .addPostFrameCallback((_) => loadWidgets(context));
    return Scaffold(
      appBar: AppBar(

        actions: <Widget>[

        ],
        title: Text("$changeableText"),
        backgroundColor: Colors.deepOrangeAccent,
      ),
      body: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          physics: BouncingScrollPhysics(

      ),

          child:IndexedStack(
            index: pageIndex,
            children: pageWidget,
          )),
      bottomNavigationBar:BottomNavigationBar(
        currentIndex: pageIndex,
        onTap: (index){
          setState(() {
            pageIndex = index;

          });
        },

        items: [
          BottomNavigationBarItem(

            icon: Icon(Icons.shopping_cart),
            title: Text("Overview")
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.star),
            title: Text("Reviews")
          )
        ],
      )
    );
}

  void stateUpdate(int index) {
    setState(() {
      firstHalf[index]+=secondHalf[index];
      cardHeight[index] = MediaQuery.of(context).size.height/2;

    });
    print(index);
    print(firstHalf[index]);
  }
}

现在,在 buildReviewsWidgets() 方法中,我正在获取所有评论数据,对其进行迭代并将其拆分为 firstHalf 和 secondHalf 列表,这样,在点击 ListTile 时,我可以简单地加入 firstHalf[index ] 和 secondHalf [index],就像我在 ListTiles 的 ontap 方法上所做的那样,但是点击列表图块根本没有任何作用.. 列表图块不会更新,基本上没有任何反应。但有趣的是,如果我 setState 并更改 changeableText 的值,它确实会更新 appbar 上的文本。谁能告诉我为什么会这样?我该如何解决?

【问题讨论】:

  • Widget w = await buildReviewsWidgets(); 你想用它实现什么?如果你有一些Future 使用FutureBuilder,不是这样的......
  • 这里发生了很多事情,并且代码的格式使得很难直观地解析和理解你正在发生的事情。不过,我的第一个猜测是,setState 正在触发您的小部件的重建就好了,但是您正在更新的内容不会导致任何可见的变化。
  • @pskink 如果您查看该方法,您会发现它正在获取文档并按照相同的方式构建小部件。
  • @pskink 实际上,我认为我不需要它,因为我不需要获取每次都会更新的恒定信息源。
  • @Abion47 在 ListView.builder 中,您可以看到 ListTile 的 subtitle 属性设置为 Text 小部件,其中 firstHalf[index] 作为字符串传递,并且在 onTap 方法上,我调用了另一个方法确实使用 setState 来更新 firstHalf[index] 的值。这还不足以触发重建吗?

标签: android flutter dart


【解决方案1】:

我刚刚清理了代码并删除了使用列表存储小部件的需要。不涉及任何带有小部件的列表立即解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2021-05-01
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多