Flutter 颤振扩展_图像:在生成期间调用setState()或markNeedsBuild()

Flutter 颤振扩展_图像:在生成期间调用setState()或markNeedsBuild(),flutter,setstate,dart-pub,statefulwidget,Flutter,Setstate,Dart Pub,Statefulwidget,我正在使用该软件包从网络加载图像,并在加载或出错时显示微光 当我试图在loadStateChanged中调用setState()时,在生成过程中调用了此错误setState()或markNeedsBuild() 事实上,我有两个小部件,一个负责从网络加载缩略图,另一个显示缩略图描述的小部件 但我希望描述显示微光时,图像无法加载或需要更长的时间加载 我在video缩略图小部件上创建了两个状态变量,应该传递给VideoDesc小部件 videoLoading = true; videoError =

我正在使用该软件包从网络加载图像,并在加载或出错时显示微光

当我试图在
loadStateChanged
中调用setState()时,在生成过程中调用了此错误
setState()或markNeedsBuild()

事实上,我有两个小部件,一个负责从网络加载缩略图,另一个显示缩略图描述的小部件

但我希望描述显示微光时,图像无法加载或需要更长的时间加载

我在
video缩略图
小部件上创建了两个状态变量,应该传递给
VideoDesc
小部件

videoLoading = true;
videoError = false;
以下是我的代码,以回购为例:

视频缩略图状态
class\u VideoThumbnailState扩展状态
使用SingleTickerProviderStateMixin{
布尔视频加载;
布尔视频错误;
动画控制器_控制器;
@凌驾
void initState(){
视频加载=真;
videoError=false;
_控制器=动画控制器(
vsync:这个,,
持续时间:常数持续时间(秒数:3),
);
super.initState();
WidgetsBinding.instance.addPostFrameCallback((){
打印(“构建过程完成”);
});
}
@凌驾
无效处置(){
_controller.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回容器(
宽度:widget.width,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
ClipRRect(
边界半径:边界半径。圆形(4.0),
子项:ExtendedImage.network(
widget.videoUrl,
宽度:widget.width,
高度:(小部件宽度)*3/4,
loadStateChanged:(ExtendedImageState状态){
开关(state.extendedImageLoadState){
案例LoadState.loading:
_controller.reset();
设置状态(){
videoError=false;
视频加载=真;
});
返回闪烁颜色(
子:容器(
装饰:盒子装饰(
边界半径:边界半径。圆形(4.0),
),
),
基本颜色:颜色。黑色12,
highlightColor:Colors.white24,
);
打破
案例LoadState.completed:
_controller.forward();
设置状态(){
videoError=false;
视频加载=错误;
});
返回衰减转换(
不透明度:_控制器,
子对象:ExtendedRawImage(
image:state.extendedImageInfo?.image,
宽度:widget.width,
高度:(小部件宽度)*3/4,
),
);
打破
案例LoadState.0失败:
_controller.reset();
state.imageProvider.execut();
设置状态(){
videoError=true;
视频加载=错误;
});
返回容器(
宽度:widget.width,
高度:(小部件宽度)*3/4,
装饰:盒子装饰(
图像:装饰图像(
图像:AssetImage(“assets/img/notfound.png”),
fit:BoxFit.fill,
),
),
);
打破
违约:
返回容器();
}
},
),
),
视频描述(
desc:widget.desc,
videoError:videoError,
视频加载:视频加载,
)
],
),
);
}
}
视频小部件
classvideodesc扩展了无状态小部件{
最终字符串描述;
最终布尔视频加载;
最终布尔视频错误;
常数视频描述({
关键点,
@需要这个.desc,
this.videoLoading=true,
this.videoError=false,
}):super(key:key);
@凌驾
小部件构建(构建上下文){
返回容器(
孩子:视频错误| |视频加载
?微光颜色(
基色:颜色。灰色[700],
highlightColor:Colors.white24,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
尺寸箱(高度:12.0),
容器(
宽度:double.infinity,
身高:8.0,
装饰:盒子装饰(
颜色:颜色。灰色[900],
边界半径:边界半径。圆形(2.0),
),
),
尺寸箱(高度:12.0),
容器(
宽度:80.0,
身高:8.0,
装饰:盒子装饰(
颜色:颜色。灰色[900],
边界半径:边界半径。圆形(2.0),
),
),
],
),
)
:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
尺寸箱(高度:12.0),
正文(
描述,
样式:TextStyle(
颜色:颜色,白色,
字体大小:11.0,
),
溢出:
class _VideoThumbnailState extends State<VideoThumbnail>
    with SingleTickerProviderStateMixin {
  bool videoLoading;
  bool videoError;

  AnimationController _controller;

  @override
  void initState() {
    videoLoading = true;
    videoError = false;

    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 3),
    );
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      print("Build Process Complete");
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.width,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          ClipRRect(
            borderRadius: BorderRadius.circular(4.0),
            child: ExtendedImage.network(
              widget.videoUrl,
              width: widget.width,
              height: (widget.width) * 3 / 4,
              loadStateChanged: (ExtendedImageState state) {
                switch (state.extendedImageLoadState) {
                  case LoadState.loading:
                    _controller.reset();

                    setState(() {
                      videoError = false;
                      videoLoading = true;
                    });

                    return Shimmer.fromColors(
                      child: Container(
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(4.0),
                        ),
                      ),
                      baseColor: Colors.black12,
                      highlightColor: Colors.white24,
                    );
                    break;

                  case LoadState.completed:
                    _controller.forward();

                    setState(() {
                      videoError = false;
                      videoLoading = false;
                    });

                    return FadeTransition(
                      opacity: _controller,
                      child: ExtendedRawImage(
                        image: state.extendedImageInfo?.image,
                        width: widget.width,
                        height: (widget.width) * 3 / 4,
                      ),
                    );

                    break;

                  case LoadState.failed:
                    _controller.reset();
                    state.imageProvider.evict();

                    setState(() {
                      videoError = true;
                      videoLoading = false;
                    });

                    return Container(
                      width: widget.width,
                      height: (widget.width) * 3 / 4,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage("assets/img/not-found.png"),
                          fit: BoxFit.fill,
                        ),
                      ),
                    );

                    break;

                  default:
                    return Container();
                }
              },
            ),
          ),
          VideoDesc(
            desc: widget.desc,
            videoError: videoError,
            videoLoading: videoLoading,
          )
        ],
      ),
    );
  }
}
class VideoDesc extends StatelessWidget {
  final String desc;
  final bool videoLoading;
  final bool videoError;

  const VideoDesc({
    Key key,
    @required this.desc,
    this.videoLoading = true,
    this.videoError = false,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: videoError || videoLoading
          ? Shimmer.fromColors(
              baseColor: Colors.grey[700],
              highlightColor: Colors.white24,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  SizedBox(height: 12.0),
                  Container(
                    width: double.infinity,
                    height: 8.0,
                    decoration: BoxDecoration(
                      color: Colors.grey[900],
                      borderRadius: BorderRadius.circular(2.0),
                    ),
                  ),
                  SizedBox(height: 12.0),
                  Container(
                    width: 80.0,
                    height: 8.0,
                    decoration: BoxDecoration(
                      color: Colors.grey[900],
                      borderRadius: BorderRadius.circular(2.0),
                    ),
                  ),
                ],
              ),
            )
          : Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                SizedBox(height: 12.0),
                Text(
                  desc,
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 11.0,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
                SizedBox(height: 5.0),
                Text(
                  "361,143,203 views",
                  style: TextStyle(
                    color: Colors.white54,
                    fontSize: 12.0,
                  ),
                ),
              ],
            ),
    );
  }
}
WidgetsBinding.instance.addPostFrameCallback(() => setState((){}));
if(!videoLoading) {
 WidgetsBinding.instance.addPostFrameCallback(() => setState((){
        videoError = false;
        videoLoading = true;  
}));
}