【问题标题】:I am getting the error setState() or markNeedsBuild() called during build我在构建期间收到错误 setState() 或 markNeedsBuild()
【发布时间】:2020-08-23 19:39:42
【问题描述】:

我试图在图像加载到我的应用程序之前显示微光效果,但我收到一条错误消息:setState() or markNeedsBuild() called during build.

...some code here...
       child: Card(
         elevation: 5,
         child: ListView.builder(
           shrinkWrap: true,
           scrollDirection: Axis.horizontal,
           physics: ScrollPhysics(),
           itemCount: widget.images.length,
           itemBuilder: (context, index) {
             var _image=widget.images[index];
             bool showImage=true;
             //todo check setState error
               NetworkImage(_image).resolve(ImageConfiguration()).addListener(
                 ImageStreamListener(
                       (info, call) {
                     if(mounted) {
                       setState(() {
                         showImage = true;
                       });
                     }
                     // do something
                   },
                 ),
               );

             return showImage?Container(
                 width: screenWidth(context)*0.4,
                 height:screenHeight(context)*0.2,
                 child: Image.network(
                   widget.images[index],
                   width: MediaQuery.of(context).size.width*0.5,
                   fit: BoxFit.cover,
                 ),
               )
                   :Container(
               width: screenWidth(context)*0.4,
               height:screenHeight(context)*0.2,
                 child: Shimmer.fromColors(
...some code here...

在注释掉这段代码后,我意识到这是违规的,但我真的很想保留它以获得微光效果。

               NetworkImage(_image).resolve(ImageConfiguration()).addListener(
                 ImageStreamListener(
                       (info, call) {
                     if(mounted) {
                       setState(() {
                         showImage = true;
                       });
                     }
                     // do something
                   },
                 ),
               );

我怎样才能绕过它?

【问题讨论】:

    标签: flutter setstate


    【解决方案1】:

    这是因为您在构建过程运行时尝试设置状态。您的侦听器在构建阶段被解雇。 尝试使用 addPostFrameCallback:

    ImageStreamListener(
      (info, call) {
        if(mounted) {
          WidgetsBinding.instance.addPostFrameCallback((_){
            setState(() {
              showImage = true;
            });
          });
        }
      },
      true 
    ),
    

    【讨论】:

    • 似乎 ImageStreamListener 只接受一个参数。我在执行此操作时收到错误消息。
    • 对不起,我的错。我正在更新答案。
    • 谢谢,这就是我要找的。​​span>
    【解决方案2】:

    您可以在下面复制粘贴运行完整代码
    你可以使用包https://pub.dev/packages/cached_network_image
    并将Shimmer 放入placeholder

    CachedNetworkImage(
          imageUrl: "http://via.placeholder.com/350x150",
          placeholder: (context, url) => Shimmer.fromColors(
            baseColor: Colors.red,
            highlightColor: Colors.yellow,
            child: Text(
              'Shimmer',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 40.0,
                fontWeight:
                FontWeight.bold,
              ),
            ),
          ),
          errorWidget: (context, url, error) => Icon(Icons.error),
        ),
    

    工作演示

    完整代码

    import 'package:cached_network_image/cached_network_image.dart';
    import 'package:flutter/material.dart';
    import 'package:shimmer/shimmer.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {  
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(       
            primarySwatch: Colors.blue,       
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
    
      void _incrementCounter() {
        setState(() {     
          _counter++;
        });
      }
    
      @override
      Widget build(BuildContext context) {    
        return Scaffold(
          appBar: AppBar(       
            title: Text(widget.title),
          ),
          body: Center(        
            child: Column(          
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                CachedNetworkImage(
                  imageUrl: "http://via.placeholder.com/350x150",
                  placeholder: (context, url) => Shimmer.fromColors(
                    baseColor: Colors.red,
                    highlightColor: Colors.yellow,
                    child: Text(
                      'Shimmer',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontSize: 40.0,
                        fontWeight:
                        FontWeight.bold,
                      ),
                    ),
                  ),
                  errorWidget: (context, url, error) => Icon(Icons.error),
                ),
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-04-12
      • 2020-03-26
      • 2021-11-14
      • 2021-04-21
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      相关资源
      最近更新 更多